BZOJ 1018 线段树维护连通性

这个题我总是想用循环完成转移,最后发现,还是手工枚举最靠谱~

BZOJ 1018 线段树维护连通性

建立线段树,线段树的每个节点(代表的是区间)维护以上六个值,true表示连通,false表示不连通,具体可以看我的代码~

 

View Code
  1 #include <iostream>

  2 #include <cstdio>

  3 #include <cstring>

  4 #include <cstdlib>

  5 #include <algorithm>

  6 

  7 #define N 111111

  8 

  9 using namespace std;

 10 

 11 struct DAT

 12 {

 13     bool v[2],s[2],x[2];

 14     void prt() {printf("s:%d      %d\nx:%d      %d\nv:%d      %d\n\n",s[0],s[1],x[0],x[1],v[0],v[1]);}

 15 }dat[N<<2];

 16 

 17 bool a[N][2][2];

 18 int n,r1,r2,c1,c2;

 19 int dx[3]={-1,0,1};

 20 int dy[3]={0,1,0};

 21 

 22 inline void build(int u,int l,int r)

 23 {

 24     if(l==r) {dat[u].s[0]=dat[u].s[1]=true;return;}

 25     int mid=(l+r)>>1;

 26     build(u<<1,l,mid); build(u<<1|1,mid+1,r);

 27 }

 28 

 29 inline void pack(DAT &u,DAT &ls,DAT &rs,int mid)

 30 {

 31     u.x[0]=ls.x[0]||(ls.s[0]&&a[mid][0][0]&&rs.x[0]&&a[mid][1][0]&&ls.s[1]);//左上-右上 

 32     u.x[1]=rs.x[1]||(rs.s[0]&&a[mid][0][0]&&ls.x[1]&&a[mid][1][0]&&rs.s[1]);//左下-右下 

 33     u.s[0]=(ls.s[0]&&a[mid][0][0]&&rs.s[0])||(ls.v[0]&&a[mid][1][0]&&rs.v[1]);//左上-左下

 34     u.s[1]=(ls.s[1]&&a[mid][1][0]&&rs.s[1])||(ls.v[1]&&a[mid][0][0]&&rs.v[0]);//右上-右下

 35     u.v[0]=(ls.s[0]&&a[mid][0][0]&&rs.v[0])||(ls.v[0]&&a[mid][1][0]&&rs.s[1]);//左上-右下

 36     u.v[1]=(ls.s[1]&&a[mid][1][0]&&rs.v[1])||(ls.v[1]&&a[mid][0][0]&&rs.s[0]);//右上-左下 

 37 }

 38 

 39 inline void updata(int u,int l,int r,int p)

 40 {

 41     if(l==r)

 42     {

 43         dat[u].x[0]=dat[u].x[1]=dat[u].v[1]=dat[u].v[0]=a[p][0][1];

 44         dat[u].s[0]=dat[u].s[1]=true;

 45         return;

 46     }

 47     int mid=(l+r)>>1;

 48     if(p<=mid) updata(u<<1,l,mid,p);

 49     else updata(u<<1|1,mid+1,r,p);

 50     pack(dat[u],dat[u<<1],dat[u<<1|1],mid);

 51 }

 52 

 53 inline void change(bool pd)

 54 {

 55     if(r1>r2) swap(r1,r2),swap(c1,c2);

 56     int dir;

 57     for(int i=0;i<3;i++)

 58         if(c1+dx[i]==c2&&r1+dy[i]==r2) dir=i;

 59     if(dir==0) a[c2][r2][0]=pd,updata(1,1,n,c2);

 60     else if(dir==1) a[c1][0][1]=pd,updata(1,1,n,c1);

 61     else a[c1][r1][0]=pd,updata(1,1,n,c1);

 62 }

 63 

 64 inline void getpack(DAT &p,int u,int L,int R,int l,int r)

 65 {

 66     if(l<=L&&r>=R) {p=dat[u];return;}

 67     int MID=(L+R)>>1;

 68     if(r<=MID) getpack(p,u<<1,L,MID,l,r);

 69     else if(l>=MID+1) getpack(p,u<<1|1,MID+1,R,l,r);

 70     else

 71     {

 72         DAT tmp1,tmp2;

 73         getpack(tmp1,u<<1,L,MID,l,MID);

 74         getpack(tmp2,u<<1|1,MID+1,R,MID+1,r);

 75         pack(p,tmp1,tmp2,MID);

 76     }

 77 }

 78 

 79 inline void getans()

 80 {

 81     if(c1>c2) swap(c1,c2),swap(r1,r2);

 82     DAT pa,pb,pc;

 83     getpack(pa,1,1,n,1,c1);

 84     getpack(pb,1,1,n,c1,c2);

 85     getpack(pc,1,1,n,c2,n);

 86     if(r1==r2)

 87     {

 88         if(r1==0)

 89         {

 90             if(pb.s[0]||(pa.x[1]&&pb.v[1])||(pc.x[0]&&pb.v[0])||(pa.x[1]&&pb.s[1]&&pc.x[0])) puts("Y");

 91             else puts("N");

 92         }

 93         else

 94         {

 95             if(pb.s[1]||(pa.x[1]&&pb.v[0])||(pc.x[0]&&pb.v[1])||(pa.x[1]&&pb.s[0]&&pc.x[0])) puts("Y");

 96             else puts("N");

 97         }

 98     }

 99     else

100     {

101         if(r1==0)

102         {

103             if(pb.v[0]||(pa.x[1]&&pb.s[1])||(pc.x[0]&&pb.s[0])) puts("Y");

104             else puts("N");

105         }

106         else

107         {

108             if(pb.v[1]||(pa.x[1]&&pb.s[0])||(pc.x[0]&&pb.s[1])) puts("Y");

109             else puts("N");

110         }

111     }

112 }

113 

114 inline void go()

115 {

116     char str[10];

117     scanf("%d",&n);

118     build(1,1,n);

119     while(scanf("%s",str))

120     {

121         if(str[0]=='E') break;

122         scanf("%d%d%d%d",&r1,&c1,&r2,&c2);

123         r1--; r2--;

124         if(str[0]=='O') change(1);

125         else if(str[0]=='C') change(0);

126         else getans();

127     }

128 }

129 

130 int main()

131 {

132     go();

133     return 0;

134 }

 

感觉这个题还是挺神的~

 

 

你可能感兴趣的:(线段树)