标签:play sed sub -- include splay bit amp top
一颗有根树,每个点有黑白两种颜色和阀值ai,若它的子树中(不包括自己)的黑色数量大于ai,则产生一点贡献。每次将一个点的颜色取反,求每次修改后的贡献。n,q<=1E5。
树剖后直接分块就行了。复杂度约为O((n+q)sqrt(nlogn)),但似乎更小?
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1E5+5; 4 /////////////////////////////////////////////////////////////////////////////// 5 int wait[maxn],wait_R[maxn],wait_C[maxn],wait_W[maxn]; 6 template<class T>inline void copy(T*A,T*B,int l,int r) 7 { 8 for(int i=l;i<=r;++i) 9 A[i-l+1]=B[i]; 10 } 11 struct block 12 { 13 int n,pos,layer,now; 14 int*f,*c; 15 block() 16 { 17 now=0; 18 } 19 void init(int x,int where,int*A) 20 { 21 delete f; 22 delete c; 23 for(int i=1;i<=x;++i) 24 wait_R[i]=A[i],wait_C[i]=0; 25 sort(wait_R+1,wait_R+x+1); 26 int size=0; 27 for(int i=1;i<=x;++i) 28 { 29 if(wait_R[i]!=wait_R[i-1]||i==1) 30 wait_W[++size]=A[i]; 31 ++wait_C[size]; 32 } 33 n=size; 34 f=new int[n+1]; 35 c=new int[n+1]; 36 now=c[0]=f[0]=0; 37 layer=where; 38 pos=1; 39 for(int i=1;i<=n;++i) 40 f[i]=wait_W[i],c[i]=wait_C[i]; 41 while(f[pos]<layer) 42 now+=c[pos],++pos; 43 } 44 inline int get() 45 { 46 return now; 47 } 48 inline void add() 49 { 50 if(layer+1==f[pos]+1) 51 now+=c[pos],++pos; 52 ++layer; 53 } 54 inline void remove() 55 { 56 if(pos&&layer-1==f[pos-1]) 57 now-=c[pos-1],--pos; 58 --layer; 59 } 60 }; 61 struct sequence 62 { 63 int*a,*tag,*bel,*tail; 64 block*B; 65 int n,sqr,tot; 66 void init(int x,int*A) 67 { 68 n=x; 69 sqr=sqrt(n+0.5); 70 a=new int[n+1]; 71 bel=new int[n+1]; 72 tag=new int[sqr+2]; 73 tail=new int[sqr+2]; 74 for(int i=0;i<=sqr+1;++i) 75 tail[i]=tag[i]=0; 76 a[0]=0; 77 for(int i=1;i<=n;++i) 78 a[i]=A[i]; 79 int L=1,R=sqr; 80 B=new block[sqr+2]; 81 tot=0; 82 while(L<=n) 83 { 84 int len=min(n,R)-L+1; 85 copy(wait,a,L,min(n,R)); 86 B[++tot].init(len,0,wait); 87 for(int i=L;i<=R;++i) 88 bel[i]=tot; 89 tail[tot]=min(n,R); 90 L+=sqr,R+=sqr; 91 } 92 } 93 inline int get() 94 { 95 int sum=0; 96 for(int i=1;i<=tot;++i) 97 sum+=B[i].now; 98 return sum; 99 } 100 inline void add(int x) 101 { 102 int i=1; 103 for(i=1;bel[i]!=bel[x];i+=sqr) 104 B[bel[i]].add(); 105 int L=i,R=tail[bel[x]]; 106 int len=R-L+1; 107 copy(wait,B[bel[x]].f,1,len); 108 for(int i=1;i<=len;++i) 109 wait[i]-=B[bel[x]].layer; 110 for(int i=L;i<=x;++i) 111 --wait[i-L+1]; 112 B[bel[x]].init(len,0,wait); 113 } 114 inline void remove(int x) 115 { 116 int i=1; 117 for(i=1;bel[i]!=bel[x];i+=sqr) 118 B[bel[i]].remove(); 119 int L=i,R=tail[bel[x]]; 120 int len=R-L+1; 121 copy(wait,B[bel[x]].f,1,len); 122 for(int i=1;i<=len;++i) 123 wait[i]+=B[bel[x]].layer; 124 for(int i=L;i<=x;++i) 125 ++wait[i-L+1]; 126 B[bel[x]].init(len,0,wait); 127 } 128 inline void addDot(int x,int y) 129 { 130 int i=1; 131 while(bel[i]!=bel[x]) 132 i+=sqr; 133 int L=i,R=tail[bel[x]]; 134 int len=R-L+1; 135 copy(wait,B[bel[x]].f,1,len); 136 for(int i=1;i<=len;++i) 137 wait[i]+=B[bel[x]].layer; 138 wait[x-L+1]+=y; 139 B[bel[x]].init(len,0,wait); 140 } 141 }S[maxn]; 142 /////////////////////////////////////////////////////////////////////////////// 143 int n,q,a[maxn]; 144 int size,head[maxn*2]; 145 int sum[maxn],fa[maxn],son[maxn],top[maxn],where[maxn],dfn[maxn],low[maxn],ti; 146 int tot,ans; 147 bool c[maxn]; 148 struct edge 149 { 150 int to,next; 151 }E[maxn*2]; 152 void dfs1(int u,int F) 153 { 154 fa[u]=F,sum[u]=1; 155 for(int i=head[u];i;i=E[i].next) 156 { 157 int v=E[i].to; 158 if(v==F) 159 continue; 160 dfs1(v,u); 161 sum[u]+=sum[v]; 162 if(sum[son[u]]<sum[v]) 163 son[u]=v; 164 } 165 } 166 void dfs2(int u,int F) 167 { 168 low[u]=dfn[u]=++ti; 169 if(son[F]==u) 170 top[u]=top[F]; 171 else 172 top[u]=u; 173 if(son[u]) 174 { 175 dfs2(son[u],u); 176 low[u]=low[son[u]]; 177 } 178 for(int i=head[u];i;i=E[i].next) 179 { 180 int v=E[i].to; 181 if(v==F||v==son[u]) 182 continue; 183 dfs2(v,u); 184 low[u]=low[v]; 185 } 186 } 187 void get(int u) 188 { 189 wait[where[u]=++tot]=a[u]; 190 if(son[u]) 191 get(son[u]); 192 } 193 void add(int u,int v) 194 { 195 E[++size].to=v; 196 E[size].next=head[u]; 197 head[u]=size; 198 } 199 void addChain(int x) 200 { 201 while(x) 202 { 203 S[top[x]].add(where[x]); 204 x=fa[top[x]]; 205 } 206 } 207 void removeChain(int x) 208 { 209 while(x) 210 { 211 S[top[x]].remove(where[x]); 212 x=fa[top[x]]; 213 } 214 } 215 int askChain(int x) 216 { 217 int sum=0; 218 while(x) 219 { 220 sum+=S[top[x]].get(); 221 x=fa[top[x]]; 222 } 223 return sum; 224 } 225 /////////////////////////////////////////////////////////////////////////////// 226 int main() 227 { 228 ios::sync_with_stdio(false); 229 cin>>n>>q; 230 for(int i=2;i<=n;++i) 231 { 232 int x; 233 cin>>x; 234 add(x,i); 235 add(i,x); 236 } 237 for(int i=1;i<=n;++i) 238 cin>>a[i]; 239 dfs1(1,1); 240 dfs2(1,1); 241 fa[1]=0; 242 for(int u=1;u<=n;++u) 243 if(top[u]==u) 244 { 245 tot=0; 246 get(u); 247 S[u].init(tot,wait); 248 } 249 while(q--) 250 { 251 int x; 252 cin>>x; 253 if(c[x]) 254 { 255 int last=askChain(x); 256 removeChain(fa[x]); 257 S[top[x]].addDot(where[x],-666666); 258 int now=askChain(x); 259 ans+=now-last; 260 } 261 else 262 { 263 int last=askChain(x); 264 addChain(fa[x]); 265 S[top[x]].addDot(where[x],666666); 266 int now=askChain(x); 267 ans+=now-last; 268 } 269 c[x]^=1; 270 cout<<ans<<" "; 271 } 272 return 0; 273 }
标签:play sed sub -- include splay bit amp top
原文地址:https://www.cnblogs.com/GreenDuck/p/11136218.html