您的位置:首页 > 其它

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

2016-01-02 15:45 465 查看
题目: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[6],l,r;
}t[maxn*4];
int road[maxn][3],n;
char s[10];
int read(){
int x=0,f=1; char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1; ch=getchar();}
while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
data M(data l,data r){
data i;
i.l=l.l; i.r=r.r;
i.b[0]=(l.b[0])||( ( (l.b[1]&&l.b[3]) || (l.b[4]&&l.b[5]) )&&(road[l.r][0])&&(road[l.r][1])&&(r.b[0]));
i.b[2]=(r.b[2])||( ( (r.b[1]&&r.b[3]) || (r.b[4]&&r.b[5]) )&&(road[l.r][0])&&(road[l.r][1])&&(l.b[2]));
i.b[1]=(l.b[1]&&r.b[1]&&road[l.r][0]) || (l.b[4]&&r.b[5]&&road[l.r][1]);
i.b[3]=(l.b[3]&&r.b[3]&&road[l.r][1]) || (l.b[5]&&r.b[4]&&road[l.r][0]);
i.b[4]=(l.b[1]&&r.b[4]&&road[l.r][0]) || (l.b[4]&&r.b[3]&&road[l.r][1]);
i.b[5]=(l.b[5]&&r.b[1]&&road[l.r][0]) || (l.b[3]&&r.b[5]&&road[l.r][1]);
return i;
}
void build(int i,int l,int r){
t[i].l=l; t[i].r=r; int mid=(l+r)/2;
if (l==r){ t[i].b[1]=t[i].b[3]=1; return; }
build(i*2,l,mid); build(i*2+1,mid+1,r);
t[i]=M(t[i*2],t[i*2+1]);
}
void change(int pos,int i){
int l=t[i].l,r=t[i].r,mid=(l+r)/2;
if (l==r){
rep(j,0,5) t[i].b[j]=road[l][2];
t[i].b[1]=t[i].b[3]=1;
return;
}
if (pos<=mid) change(pos,i*2); else change(pos,i*2+1);
t[i]=M(t[i*2],t[i*2+1]);
}
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==1) road[y0][0]=flag; else road[y0][1]=flag;
} else road[y0][2]=flag;
change(y0,1);
}
data ask(int i,int tl,int tr){
int l=t[i].l,r=t[i].r,mid=(l+r)/2;
if (l==tl&&r==tr) return t[i];
if (tr<=mid) return ask(i*2,tl,tr);
else if (tl>mid) return ask(i*2+1,tl,tr);
else return M(ask(i*2,tl,mid),ask(i*2+1,mid+1,tr));
}
bool query(int x0,int y0,int x1,int y1){
if (y0>y1) swap(x0,x1),swap(y0,y1);
data x=ask(1,1,y0),y=ask(1,y0,y1),z=ask(1,y1,n);
if (x0==x1) {
if (x0==1){
if (y.b[1]) return 1;
if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[3]) return 1;
if ((y.b[4])&&(y.b[2]||z.b[0])) return 1;
if ((y.b[5])&&(x.b[2]||y.b[0])) return 1;
return 0;
}
else {
if (y.b[3]) return 1;
if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[1]) return 1;
if ((y.b[5])&&(y.b[2]||z.b[0])) return 1;
if ((y.b[4])&&(x.b[2]||y.b[0])) return 1;
return 0;
}
}
else {
if (x0==1){
if (y.b[4]) return 1;
if ((x.b[2]||y.b[0])&&y.b[3]) return 1;
if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[5]) return 1;
if ((y.b[2]||z.b[0])&&y.b[1]) return 1;
return 0;
}
else {
if (y.b[5]) return 1;
if ((x.b[2]||y.b[0])&&y.b[1]) return 1;
if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[4]) return 1;
if ((y.b[2]||z.b[0])&&y.b[3]) return 1;
return 0;
}
}

}
int main(){
n=read();
build(1,1,n);
int x0,x1,y0,y1;
while (1){
scanf("%s",s);
if (s[0]=='E') break;
x0=read(); y0=read(); x1=read(); y1=read();
if (s[0]=='O') change(x0,y0,x1,y1,1);
else if (s[0]=='C') change(x0,y0,x1,y1,0);
else printf("%c\n",query(x0,y0,x1,y1)?'Y':'N');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: