树上区间修改,用树链剖分+线段树
只是这个题合并的时候不好有点坑,调了半天
然后不知道为什么用现成的树剖求lca居然要T,改了倍增才过
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,m,shen[100010],head[100010],next[200020],zhi[200020],col[100010],ed,son[100010],fa[100010],dfn[100010],tot,top[100010]; 34 int ft[100010][18]; 35 void dfs1(int x) 36 { 37 son[x]=1; 38 for(int i=1;i<=17;i++) 39 { 40 if(shen[x]<(1<<i))break; 41 ft[x][i]=ft[ft[x][i-1]][i-1]; 42 } 43 for(int i=head[x];i;i=next[i])if(zhi[i]!=ft[x][0]) 44 { 45 shen[zhi[i]]=shen[x]+1; 46 ft[zhi[i]][0]=x; 47 dfs1(zhi[i]); 48 son[x]+=son[zhi[i]]; 49 } 50 } 51 void dfs2(int x,int chain) 52 { 53 dfn[x]=++tot;top[x]=chain; 54 int k=0; 55 for(int i=head[x];i;i=next[i]) 56 if(shen[zhi[i]]>shen[x]&&son[k]<son[zhi[i]]) 57 k=zhi[i]; 58 if(!k)return; 59 dfs2(k,chain); 60 for(int i=head[x];i;i=next[i]) 61 if(shen[zhi[i]]>shen[x]&&k!=zhi[i]) 62 dfs2(zhi[i],zhi[i]); 63 } 64 void add(int a,int b) 65 { 66 next[++ed]=head[a],head[a]=ed,zhi[ed]=b; 67 next[++ed]=head[b],head[b]=ed,zhi[ed]=a; 68 } 69 struct segtree 70 { 71 int sum,lc,rc,l,r,add; 72 segtree(){lc=rc=sum=0;} 73 }t[400040]; 74 void build(int k,int l,int r) 75 { 76 t[k].l=l;t[k].r=r;t[k].sum=1;t[k].add=0; 77 if(l==r)return; 78 int mid=(l+r)>>1; 79 build(k<<1,l,mid);build(k<<1|1,mid+1,r); 80 } 81 void update(int k,int a,int x) 82 { 83 int l=t[k].l,r=t[k].r,mid=(l+r)>>1,p1=k<<1,p2=p1|1; 84 if(l==r) 85 { 86 t[k].sum=1,t[k].lc=t[k].rc=x; 87 return ; 88 } 89 if(a<=mid)update(p1,a,x); 90 else update(p2,a,x); 91 t[k].sum=t[p1].sum+t[p2].sum; 92 if(t[p1].rc==t[p2].lc)t[k].sum--; 93 t[k].lc=t[p1].lc,t[k].rc=t[p2].rc; 94 } 95 void down(int k) 96 { 97 if(!t[k].add)return ; 98 int p1=k<<1,p2=p1|1; 99 t[p1].add=t[p2].add=t[k].add; 100 t[p1].sum=t[p2].sum=1; 101 t[p1].lc=t[p1].rc=t[p2].lc=t[p2].rc=t[k].add; 102 t[k].add=0; 103 if(t[p1].l==t[p1].r)col[t[p1].l]=t[p1].add; 104 if(t[p2].l==t[p2].r)col[t[p2].l]=t[p2].add; 105 } 106 void change(int k,int x,int y,int c) 107 { 108 int l=t[k].l,r=t[k].r; 109 if(l==x&&r==y) 110 {t[k].lc=t[k].rc=c;t[k].sum=1;t[k].add=c;return;} 111 down(k); 112 int mid=(l+r)>>1; 113 if(mid>=y)change(k<<1,x,y,c); 114 else if(mid<x)change(k<<1|1,x,y,c); 115 else 116 { 117 change(k<<1,x,mid,c); 118 change(k<<1|1,mid+1,y,c); 119 } 120 t[k].lc=t[k<<1].lc;t[k].rc=t[k<<1|1].rc; 121 if(t[k<<1].rc^t[k<<1|1].lc)t[k].sum=t[k<<1].sum+t[k<<1|1].sum; 122 else t[k].sum=t[k<<1].sum+t[k<<1|1].sum-1; 123 } 124 int query(int k,int x,int y) 125 { 126 int l=t[k].l,r=t[k].r; 127 if(l==x&&r==y)return t[k].sum; 128 down(k); 129 int mid=(l+r)>>1; 130 if(mid>=y)return query(k<<1,x,y); 131 else if(mid<x)return query(k<<1|1,x,y); 132 else 133 { 134 int tmp=1; 135 if(t[k<<1].rc^t[k<<1|1].lc)tmp=0; 136 return query(k<<1,x,mid)+query(k<<1|1,mid+1,y)-tmp; 137 } 138 } 139 //int lca(int x,int y) 140 //{ 141 // while(top[x]!=top[y]) 142 // { 143 // if(shen[top[x]]>shen[top[y]])x=fa[top[x]]; 144 // else y=fa[top[y]]; 145 // } 146 // return shen[x]>shen[y]?y:x; 147 //} 148 int lca(int x,int y) 149 { 150 if(shen[x]<shen[y])swap(x,y); 151 int t=shen[x]-shen[y]; 152 for(int i=0;i<=17;i++) 153 if(t&(1<<i))x=ft[x][i]; 154 for(int i=17;i>=0;i--) 155 if(ft[x][i]!=ft[y][i]) 156 {x=ft[x][i];y=ft[y][i];} 157 if(x==y)return x; 158 return ft[x][0]; 159 } 160 void change__(int x,int f,int c) 161 { 162 while(top[x]!=top[f]) 163 { 164 change(1,dfn[top[x]],dfn[x],c); 165 x=ft[top[x]][0]; 166 } 167 change(1,dfn[f],dfn[x],c); 168 } 169 int getc(int k,int x) 170 { 171 int l=t[k].l,r=t[k].r; 172 if(l==r)return t[k].lc; 173 down(k); 174 int mid=(l+r)>>1; 175 if(x<=mid)return getc(k<<1,x); 176 else return getc(k<<1|1,x); 177 } 178 int ad(int x,int f) 179 { 180 int ret=0; 181 while(top[x]!=top[f]) 182 { 183 ret+=query(1,dfn[top[x]],dfn[x]); 184 if(getc(1,dfn[top[x]])==getc(1,dfn[ft[top[x]][0]]))ret--; 185 x=ft[top[x]][0]; 186 } 187 ret+=query(1,dfn[f],dfn[x]); 188 return ret; 189 } 190 int CSC() 191 { 192 freopen("in.in","r",stdin); 193 freopen("out.out","w",stdout); 194 inin(n);inin(m); 195 re(i,1,n)inin(col[i]); 196 re(i,1,n-1) 197 { 198 int q,w; 199 inin(q),inin(w); 200 add(q,w); 201 } 202 dfs1(1); 203 dfs2(1,1); 204 build(1,1,n); 205 for(int i=1;i<=n;i++) 206 change(1,dfn[i],dfn[i],col[i]); 207 re(i,1,m) 208 { 209 char opt[5];strin(opt); 210 if(opt[0]=='C') 211 { 212 int q,w,e; 213 inin(q),inin(w),inin(e); 214 int r=lca(q,w); 215 change__(q,r,e),change__(w,r,e); 216 } 217 if(opt[0]=='Q') 218 { 219 int q,w; 220 inin(q),inin(w); 221 int e=lca(q,w); 222 printf("%d ",ad(q,e)+ad(w,e)-1); 223 } 224 } 225 return 0; 226 }