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]:
",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:
",x.l,x.r,x.c[0],x.c[1]);
 29     printf("	UU:%d UD:%d DD:%d DU:%d LL:%d RR:%d
",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
");
146             else printf("N
");
147         }
148     }
149     return 0;
150 }
原文地址:https://www.cnblogs.com/Ressed/p/9760993.html