[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 }