[bzoj3553] [Shoi2014]三叉神经树

  链剖一波,我们只关心末端"001"和"011"这两种输入被改变后会改变输出的情况。。不然就是单点修改。

  线段树需要维护区间右端开始连续的"001""011"长度。。修改的时候就把整段连续的都改了,最后加个单点修改。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 using namespace std;
  5 const int maxn=500233;
  6 struct zs{
  7     int too,pre;
  8 }e[maxn];int tot1,last[maxn];
  9 int lc[maxn<<1],rc[maxn<<1],sz1[maxn<<1],mx0[maxn<<1],mx1[maxn<<1],tag[maxn<<1],tot;//0:001  1:110 2:000 3:111
 10 int bel[maxn],len[maxn],sz[maxn],dfn[maxn],tim,pos[maxn],st[maxn],top,rt[maxn];
 11 int mp[maxn*3],fa[maxn*3];
 12 int i,j,k,n,m,LEN,P,R;
 13 bool ans;
 14  
 15 int ra;char rx;
 16 inline int read(){
 17     rx=getchar(),ra=0;
 18     while(rx<'0'||rx>'9')rx=getchar();
 19     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
 20 }
 21  
 22 inline void upd(int x){
 23     int l=lc[x],r=rc[x];
 24     mx0[x]=mx0[r]==sz1[r]?mx0[l]+mx0[r]:mx0[r],
 25     mx1[x]=mx1[r]==sz1[r]?mx1[l]+mx1[r]:mx1[r];
 26 }
 27 inline void pushdown(int x){
 28     int l=lc[x],r=rc[x];
 29     if(tag[x]==1)
 30         mx1[l]=sz1[l],mx1[r]=sz1[r],
 31         tag[r]=tag[l]=1,
 32         mx0[l]=mx0[r]=0,
 33         tag[x]=-1;
 34     if(tag[x]==0)
 35         mx0[l]=sz1[l],mx0[r]=sz1[r],
 36         tag[l]=tag[r]=0,
 37         mx1[l]=mx1[r]=0,
 38         tag[x]=-1;
 39 }
 40  
 41 void query0(int x,int a,int b){
 42 //  if(!mx0[x])return;
 43     if(b<=R&&mx0[x]==sz1[x]){
 44         LEN+=mx0[x],
 45         tag[x]=1,mx1[x]=sz1[x],mx0[x]=0;
 46         return;
 47     }
 48     if(R-LEN>b-mx1[x]||a==b)return;
 49     if(tag[x]!=-1)pushdown(x);
 50     int mid=a+b>>1;
 51     if(R>mid){
 52         query0(rc[x],mid+1,b);
 53         if(mid+LEN==R&&mx0[lc[x]])query0(lc[x],a,mid);
 54     }else query0(lc[x],a,mid);
 55     upd(x);
 56 }
 57 void query1(int x,int a,int b){
 58 //  if(!mx1[x])return;
 59     if(b<=R&&mx1[x]==sz1[x]){
 60         LEN+=mx1[x],
 61         tag[x]=0,mx0[x]=mx1[x],mx1[x]=0;
 62         return;
 63     }
 64     if(R-LEN>b-mx0[x]||a==b)return;
 65     if(tag[x]!=-1)pushdown(x);
 66     int mid=a+b>>1;
 67     if(R>mid){
 68         query1(rc[x],mid+1,b);
 69         if(mid+LEN==R)query1(lc[x],a,mid);
 70     }else query1(lc[x],a,mid);
 71     upd(x);
 72 }
 73 void add1(int x,int a,int b){
 74     if(a==b){
 75         if(tag[x]==1)tag[x]=3,mx1[x]=0;else
 76         if(tag[x]==2)tag[x]=0,mx0[x]=1;else puts("gg");
 77         return;
 78     }
 79     if(tag[x]!=-1)pushdown(x);
 80     int mid=a+b>>1;
 81     if(LEN<=mid)add1(lc[x],a,mid);else add1(rc[x],mid+1,b);
 82     upd(x);
 83 }
 84 void add0(int x,int a,int b){
 85     if(a==b){
 86         if(tag[x]==0)tag[x]=2,mx0[x]=0;else
 87         if(tag[x]==3)tag[x]=1,mx1[x]=1;else puts("gg");
 88         return;
 89     }
 90     if(tag[x]!=-1)pushdown(x);
 91     int mid=a+b>>1;
 92     if(LEN<=mid)add0(lc[x],a,mid);else add0(rc[x],mid+1,b);
 93     upd(x);
 94 }
 95  
 96 void build(int &x,int a,int b){
 97     x=++tot,tag[x]=-1,sz1[x]=b-a+1;
 98     if(a==b){
 99         if(mp[st[a]]==0)tag[x]=2;else
100         if(mp[st[a]]==1)mx0[x]=1,tag[x]=0;else
101         if(mp[st[a]]==2)mx1[x]=1,tag[x]=1;else
102         tag[x]=3;
103 //      printf("build:  %d  %d\n",st[a],mp[st[a]]);
104         return;
105     }
106     int mid=a+b>>1;
107     build(lc[x],a,mid),build(rc[x],mid+1,b);
108     upd(x);
109 }
110 int dfs(int x){
111     if(x>n)return mp[x];
112     int i;sz[x]=1;
113     for(i=last[x];i;i=e[i].pre)mp[x]+=dfs(e[i].too),sz[x]+=sz[e[i].too];
114     return mp[x]>1;
115 }
116 void dfs2(int x,int chain){
117     bel[x]=chain;int i,mx=0;
118     dfn[x]=++tim,st[++top]=x,
119     pos[x]=dfn[x]-dfn[chain]+1;//printf("dfs2:  x:%d   bel:%d  pos:%d\n",x,chain,pos[x]);
120     for(i=last[x];i;i=e[i].pre)
121         if(sz[e[i].too]>sz[mx])mx=e[i].too;
122     if(!mx){
123         len[chain]=top,build(rt[chain],1,top),top=0;
124         return;
125     }
126     dfs2(mx,chain);
127     for(i=last[x];i;i=e[i].pre)
128         if(e[i].too!=mx)dfs2(e[i].too,e[i].too);
129 }
130  
131 inline void run(int x){
132     bool flag=!mp[x];int num1;//printf("    fa:%d  add:%d\n",fa[x],flag);
133     mp[x]^=1,x=fa[x];
134     if(flag){
135         while(1){
136             LEN=0,R=pos[x],query0(rt[bel[x]],1,len[bel[x]]);//printf("LEN:  %d\n",LEN);
137             LEN=pos[x]-LEN;
138             if(LEN>0){add1(rt[bel[x]],1,len[bel[x]]);break;}
139             else if(bel[x]==1){ans=1;break;}
140             else x=fa[bel[x]];
141         }
142     }
143     else{
144         while(1){
145             LEN=0,R=pos[x],query1(rt[bel[x]],1,len[bel[x]]);//printf("LEN:  %d\n",LEN);
146             LEN=pos[x]-LEN;
147             if(LEN>0){add0(rt[bel[x]],1,len[bel[x]]);break;}
148             else if(bel[x]==1){ans=0;break;}
149             else x=fa[bel[x]];
150         }
151     }
152 }
153  
154 inline void insert(int a,int b){
155     if(b<=n)
156         e[++tot1].too=b,e[tot1].pre=last[a],last[a]=tot1;
157     fa[b]=a;
158 }
159 int main(){
160     n=read();
161     for(i=1;i<=n;i++)insert(i,read()),insert(i,read()),insert(i,read());
162     for(i=n+1;i<=3*n+1;i++)mp[i]=read(),mp[fa[i]]+=mp[i];
163     ans=dfs(1);dfs2(1,1);//printf("ans:  %d\n",ans);
164     m=read();
165     while(m--)
166         run(read()),
167         puts(ans?"1":"0");
168     return 0;
169 }
View Code

 

posted @ 2016-06-19 13:55  czllgzmzl  阅读(163)  评论(0编辑  收藏  举报