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[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;
}

 

posted on 2016-01-02 15:45  ctlchild  阅读(...)  评论(... 编辑 收藏

导航