• 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 }
  • 相关阅读:
    makefile 中 $@ $^ %< 使用
    makefile中的自动化变量$@,$%,$
    linux grep命令
    wc命令
    linux下echo命令
    winscp和putty提取固件教程
    WinSCP和PuTTY在刷openwrt固件的使用教程
    OPENWRT学习笔记入门篇
    第五章 并发性:互斥和同步
    getCurrentSession()和getOpenSession()的区别
  • 原文地址:https://www.cnblogs.com/Ressed/p/9760993.html
Copyright © 2020-2023  润新知