BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1018

用线段树维护区间连通性,对于每一个区间记录6个域表示(左上,左下)(左上,右上)(右上,右下)(左下,右下)(左上,右下)(左下,右上)的连通情况。

因为是与相邻点的关系所以维护一个数组表示当前列x与列x+1的连边情况和当前列x的第一行与第二行的连边情况。

然后就是区间合并。。各种分类讨论。。

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define ll long long
#define maxn 100500
#define mm 998244353
using namespace std;
struct data{int b[],l,r;
}t[maxn*];
int road[maxn][],n;
char s[];
int read(){
int x=,f=; char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-; ch=getchar();}
while (isdigit(ch)){x=x*+ch-''; ch=getchar();}
return x*f;
}
data M(data l,data r){
data i;
i.l=l.l; i.r=r.r;
i.b[]=(l.b[])||( ( (l.b[]&&l.b[]) || (l.b[]&&l.b[]) )&&(road[l.r][])&&(road[l.r][])&&(r.b[]));
i.b[]=(r.b[])||( ( (r.b[]&&r.b[]) || (r.b[]&&r.b[]) )&&(road[l.r][])&&(road[l.r][])&&(l.b[]));
i.b[]=(l.b[]&&r.b[]&&road[l.r][]) || (l.b[]&&r.b[]&&road[l.r][]);
i.b[]=(l.b[]&&r.b[]&&road[l.r][]) || (l.b[]&&r.b[]&&road[l.r][]);
i.b[]=(l.b[]&&r.b[]&&road[l.r][]) || (l.b[]&&r.b[]&&road[l.r][]);
i.b[]=(l.b[]&&r.b[]&&road[l.r][]) || (l.b[]&&r.b[]&&road[l.r][]);
return i;
}
void build(int i,int l,int r){
t[i].l=l; t[i].r=r; int mid=(l+r)/;
if (l==r){ t[i].b[]=t[i].b[]=; return; }
build(i*,l,mid); build(i*+,mid+,r);
t[i]=M(t[i*],t[i*+]);
}
void change(int pos,int i){
int l=t[i].l,r=t[i].r,mid=(l+r)/;
if (l==r){
rep(j,,) t[i].b[j]=road[l][];
t[i].b[]=t[i].b[]=;
return;
}
if (pos<=mid) change(pos,i*); else change(pos,i*+);
t[i]=M(t[i*],t[i*+]);
}
void change(int x0,int y0,int x1,int y1,int flag){
if (y0>y1) swap(x0,x1),swap(y0,y1);
if (x0==x1) {
if (x0==) road[y0][]=flag; else road[y0][]=flag;
} else road[y0][]=flag;
change(y0,);
}
data ask(int i,int tl,int tr){
int l=t[i].l,r=t[i].r,mid=(l+r)/;
if (l==tl&&r==tr) return t[i];
if (tr<=mid) return ask(i*,tl,tr);
else if (tl>mid) return ask(i*+,tl,tr);
else return M(ask(i*,tl,mid),ask(i*+,mid+,tr));
}
bool query(int x0,int y0,int x1,int y1){
if (y0>y1) swap(x0,x1),swap(y0,y1);
data x=ask(,,y0),y=ask(,y0,y1),z=ask(,y1,n);
if (x0==x1) {
if (x0==){
if (y.b[]) return ;
if ((x.b[]||y.b[])&&(y.b[]||z.b[])&&y.b[]) return ;
if ((y.b[])&&(y.b[]||z.b[])) return ;
if ((y.b[])&&(x.b[]||y.b[])) return ;
return ;
}
else {
if (y.b[]) return ;
if ((x.b[]||y.b[])&&(y.b[]||z.b[])&&y.b[]) return ;
if ((y.b[])&&(y.b[]||z.b[])) return ;
if ((y.b[])&&(x.b[]||y.b[])) return ;
return ;
}
}
else {
if (x0==){
if (y.b[]) return ;
if ((x.b[]||y.b[])&&y.b[]) return ;
if ((x.b[]||y.b[])&&(y.b[]||z.b[])&&y.b[]) return ;
if ((y.b[]||z.b[])&&y.b[]) return ;
return ;
}
else {
if (y.b[]) return ;
if ((x.b[]||y.b[])&&y.b[]) return ;
if ((x.b[]||y.b[])&&(y.b[]||z.b[])&&y.b[]) return ;
if ((y.b[]||z.b[])&&y.b[]) return ;
return ;
}
} }
int main(){
n=read();
build(,,n);
int x0,x1,y0,y1;
while (){
scanf("%s",s);
if (s[]=='E') break;
x0=read(); y0=read(); x1=read(); y1=read();
if (s[]=='O') change(x0,y0,x1,y1,);
else if (s[]=='C') change(x0,y0,x1,y1,);
else printf("%c\n",query(x0,y0,x1,y1)?'Y':'N');
}
return ;
}
上一篇:App域名劫持之DNS高可用 - 开源版HttpDNS方案详解(转)


下一篇:linux查看端口及端口详解