bzoj1018/luogu4246 堵塞的交通 (线段树)
对于一个区间四个角的点,可以用线段树记下来它们两两的联通情况
区间[l,r]通过两个子区间[l,m],[m+1,r]来更新,相当于合并[l,m],[m+1,r],用(m,m+1)这条边来合并
查询a,b答案的话,不仅可以直接从[a,b]区间连通,也有可能从旁边绕了一圈
总之细节很多 懒得写了
升级版:suoi33 诡异的交通
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=1e5+10; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 struct Node{ 16 bool ll,rr,uu,ud,du,dd; 17 int c[2],l,r; 18 Node(bool a=0,bool b=0,bool cr=0,bool d=0,bool e=0,bool f=0,int x=0,int y=0,int i=0,int j=0){ 19 ll=a,rr=b,uu=cr,ud=d,du=e,dd=f; 20 l=x,r=y;c[0]=i,c[1]=j; 21 } 22 }t[maxn*4]; 23 int N,pct; 24 bool con[maxn][2]; 25 26 inline void print(Node x){ 27 printf("[%d,%d]->[%d,%d]&[%d,%d]:\n",x.l,x.r,t[x.c[0]].l,t[x.c[0]].r,t[x.c[1]].l,t[x.c[1]].r); 28 // printf("[%d,%d]->%d,%d:\n",x.l,x.r,x.c[0],x.c[1]); 29 printf("\tUU:%d UD:%d DD:%d DU:%d LL:%d RR:%d\n",x.uu,x.ud,x.dd,x.du,x.ll,x.rr); 30 } 31 inline void flash(Node &x){ 32 x.uu|=(x.ud&&x.rr)||(x.ll&&x.du)||(x.ll&&x.dd&&x.rr); 33 x.dd|=(x.du&&x.rr)||(x.ll&&x.ud)||(x.ll&&x.uu&&x.rr); 34 x.ud|=(x.uu&&x.rr)||(x.ll&&x.dd)||(x.ll&&x.du&&x.rr); 35 x.du|=(x.dd&&x.rr)||(x.ll&&x.uu)||(x.ll&&x.ud&&x.rr); 36 } 37 Node operator + (Node a,Node b){ 38 Node p; 39 p.l=a.l,p.r=b.r; 40 int m=a.r; 41 p.uu=(a.uu&&con[m][0]&&b.uu)||(a.ud&&con[m][1]&&b.du); 42 p.dd=(a.dd&&con[m][1]&&b.dd)||(a.du&&con[m][0]&&b.ud); 43 p.ud=(a.uu&&con[m][0]&&b.ud)||(a.ud&&con[m][1]&&b.dd); 44 p.du=(a.dd&&con[m][1]&&b.du)||(a.du&&con[m][0]&&b.uu); 45 p.ll=a.ll||(a.uu&&con[m][0]&&b.ll&&con[m][1]&&a.dd); 46 p.rr=b.rr||(b.uu&&con[m][0]&&a.rr&&con[m][1]&&b.dd); 47 flash(p); 48 // print(p); 49 return p; 50 } 51 52 inline void update(int p){ 53 int l=t[p].c[0],r=t[p].c[1]; 54 if(l&&r)t[p]=t[t[p].c[0]]+t[t[p].c[1]]; 55 t[p].c[0]=l,t[p].c[1]=r; 56 } 57 58 void build(int &p,int l,int r){ 59 p=++pct; 60 if(l==r) t[p]=Node(0,0,1,0,0,1,l,r,0,0); 61 else{ 62 int m=l+r>>1; 63 build(t[p].c[0],l,m); 64 build(t[p].c[1],m+1,r); 65 update(p);//print(t[p]); 66 } 67 } 68 69 void query(int p,int l,int r,int x,int y,Node &re){ 70 if(x<=l&&r<=y){ 71 if(!re.l&&!re.r) re=t[p]; 72 else re=re+t[p]; 73 }else{ 74 int m=l+r>>1; 75 if(x<=m) query(t[p].c[0],l,m,x,y,re); 76 if(y>=m+1) query(t[p].c[1],m+1,r,x,y,re); 77 } 78 } 79 80 void change1(int p,int l,int r,int x){ 81 if(l<r){ 82 int m=l+r>>1; 83 if(x<=m) change1(t[p].c[0],l,m,x); 84 else change1(t[p].c[1],m+1,r,x); 85 update(p); 86 // print(t[p]); 87 } 88 } 89 void change2(int p,int l,int r,int x,bool b){ 90 if(l==r){ 91 t[p].ud=t[p].du=t[p].ll=t[p].rr=b; 92 }else{ 93 int m=l+r>>1; 94 if(x<=m) change2(t[p].c[0],l,m,x,b); 95 else change2(t[p].c[1],m+1,r,x,b); 96 update(p); 97 } 98 } 99 100 inline void solve1(int r1,int c1,int r2,int c2,bool b){ 101 if(r1==r2){ 102 c1=min(c1,c2); 103 con[c1][r1-1]=b; 104 change1(1,1,N,c1); 105 }else{ 106 change2(1,1,N,c1,b); 107 } 108 } 109 110 inline bool solve2(int r1,int c1,int r2,int c2){ 111 Node a,b,c; 112 if(c1>c2) swap(r1,r2),swap(c1,c2); 113 query(1,1,N,1,c1,a); 114 query(1,1,N,c1,c2,b); 115 query(1,1,N,c2,N,c); 116 //print(a);print(b);print(c); 117 b.ll|=a.rr,b.rr|=c.ll; 118 flash(b); 119 if(r1==1){ 120 if(r2==2) return b.ud; 121 else return b.uu; 122 }else{ 123 if(r2==2) return b.dd; 124 else return b.du; 125 } 126 } 127 128 int main(){ 129 //freopen("","r",stdin); 130 int i,j,k; 131 N=rd(); 132 // for(i=1;i<N;i++) con[i][0]=con[i][1]=1; 133 build(i,1,N); 134 while(1){ 135 char s[10]; 136 scanf("%s",s); 137 if(s[0]=='E') break; 138 int a=rd(),b=rd(),c=rd(),d=rd(); 139 if(s[0]=='O'){ 140 solve1(a,b,c,d,1); 141 }else if(s[0]=='C'){ 142 solve1(a,b,c,d,0); 143 }else{ 144 bool x=solve2(a,b,c,d); 145 if(x) printf("Y\n"); 146 else printf("N\n"); 147 } 148 } 149 return 0; 150 }