1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+5,inf=0x3f3f3f3f; 4 int next[2*N],head[2*N],to[N*2],d[N],fa[N],v[2*N],seg[4*N],rev[4*N],top[N],size[N],son[N],w[N]; 5 int n; 6 int m,q,p,tot,cnt; 7 int sum,ma; 8 struct node{ 9 int lc,rc,sum,col; 10 }tree[N]; 11 void ADD(int k,int l,int r,int v) 12 { 13 tree[k].lc=tree[k].rc=v; 14 tree[k].sum=1; 15 tree[k].col=v; 16 return ; 17 } 18 void pushdown(int k,int l,int r,int mid) 19 { 20 if(!tree[k].col)return ; 21 ADD(k<<1,l,mid,tree[k].col); 22 ADD(k<<1|1,mid+1,r,tree[k].col); 23 tree[k].col=0; 24 } 25 void dfs1(int s,int ff) 26 { 27 size[s]=1;d[s]=d[ff]+1;fa[s]=ff; 28 for(int i=head[s],t;i,t=to[i];i=next[i]) 29 { 30 if(t!=fa[s]) 31 { 32 dfs1(t,s); 33 size[s]+=size[t]; 34 if(size[t]>size[son[s]])son[s]=t; 35 } 36 } 37 } 38 void dfs2(int s) 39 { 40 if(son[s]) 41 { 42 seg[son[s]]=++seg[0]; 43 top[son[s]]=top[s]; 44 rev[seg[0]]=son[s]; 45 dfs2(son[s]); 46 } 47 for(int i=head[s],t;t=to[i],i;i=next[i]) 48 { 49 if(!top[t]) 50 { 51 seg[t]=++seg[0]; 52 rev[seg[0]]=t; 53 top[t]=t; 54 dfs2(t); 55 } 56 } 57 } 58 void update(int k) 59 { 60 tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; 61 if(tree[k<<1].rc==tree[k<<1|1].lc)tree[k].sum--; 62 tree[k].lc=tree[k<<1].lc; 63 tree[k].rc=tree[k<<1|1].rc; 64 } 65 void build(int k,int l,int r) 66 { 67 if(l==r) 68 { 69 tree[k].lc=tree[k].rc=w[rev[l]]; 70 tree[k].sum=1; 71 return ; 72 } 73 int mid=l+r>>1; 74 build(k<<1,l,mid); 75 build(k<<1|1,mid+1,r); 76 update(k); 77 } 78 node query2(int k,int l,int r,int x,int y) 79 { 80 if(l>=x&&r<=y) 81 { 82 return tree[k]; 83 } 84 int mid=l+r>>1; 85 pushdown(k,l,r,mid); 86 if(mid>=x) 87 { 88 if(mid<y) 89 { 90 node res,ll=query2(k<<1,l,mid,x,y),rr=query2(k<<1|1,mid+1,r,x,y); 91 res.sum=ll.sum+rr.sum+(ll.rc==rr.lc?-1:0); 92 res.lc=ll.lc;res.rc=rr.rc; 93 return res; 94 } 95 else return query2(k<<1,l,mid,x,y); 96 } 97 else return query2(k<<1|1,mid+1,r,x,y); 98 } 99 int query1(int x,int y) 100 { 101 //这里可能不是很好理解,但是把a、b当做现任和备胎可能会好想一些(机房大佬lhy指点) 102 int sum=0,a=0,b=0; 103 int fx=top[x],fy=top[y]; 104 while(fx!=fy) 105 { 106 if(d[fx]<d[fy])swap(x,y),swap(fx,fy),swap(a,b); 107 node res=query2(1,1,n,seg[fx],seg[x]); 108 sum+=res.sum; 109 if(res.rc==a)sum--; 110 a=res.lc; 111 x=fa[fx];fx=top[x]; 112 } 113 if(d[x]>d[y])swap(x,y),swap(a,b); 114 node res=query2(1,1,n,seg[x],seg[y]); 115 sum+=res.sum; 116 if(res.lc==a) sum--; 117 if(res.rc==b) sum--; 118 return sum; 119 } 120 int read() 121 { 122 int f=1;char ch; 123 while((ch=getchar())<‘0‘||ch>‘9‘) 124 if(ch==‘-‘)f=-1; 125 int res=ch-‘0‘; 126 while((ch=getchar())>=‘0‘&&ch<=‘9‘) 127 res=res*10+ch-‘0‘; 128 return res*f; 129 } 130 void write(int x) 131 { 132 if(x<0) 133 { 134 putchar(‘-‘); 135 x=-x; 136 } 137 if(x>9)write(x/10); 138 putchar(x%10+‘0‘); 139 } 140 void add(int x,int y) 141 { 142 next[++tot]=head[x]; 143 head[x]=tot; 144 to[tot]=y; 145 } 146 void change2(int k,int l,int r,int x,int y,int v) 147 { 148 if(l>=x&&r<=y)return ADD(k,l,r,v); 149 int mid=l+r>>1; 150 pushdown(k,l,r,mid); 151 if(mid>=x)change2(k<<1,l,mid,x,y,v); 152 if(mid<y)change2(k<<1|1,mid+1,r,x,y,v); 153 update(k); 154 } 155 void change1(int x,int y,int v) 156 { 157 int fx=top[x],fy=top[y]; 158 while(fx!=fy) 159 { 160 if(d[fx]<d[fy])swap(x,y),swap(fx,fy); 161 change2(1,1,n,seg[fx],seg[x],v); 162 x=fa[fx];fx=top[x]; 163 } 164 if(d[x]>d[y])swap(x,y); 165 change2(1,1,n,seg[x],seg[y],v); 166 } 167 int main() 168 { 169 n=read();m=read(); 170 for(int i=1;i<=n;i++)w[i]=read(); 171 for(int i=1;i<n;i++) 172 { 173 int x,y; 174 x=read();y=read(); 175 add(x,y);add(y,x); 176 } 177 dfs1(1,0); 178 seg[0]=top[1]=rev[1]=seg[1]=1; 179 dfs2(1); 180 build(1,1,n); 181 while(m--) 182 { 183 char ch;int a,b; 184 while((ch=getchar())<‘A‘||ch>‘Z‘); 185 //这个地方读入一定要小心!我的爆零经验就是前车之鉴!!! 186 a=read();b=read(); 187 if(ch==‘C‘) 188 { 189 int c;c=read(); 190 change1(a,b,c); 191 } 192 else 193 { 194 write(query1(a,b)); 195 putchar(‘\n‘); 196 } 197 } 198 return 0; 199 } 200 //硬生生凑个200行 ~(~ ̄▽ ̄)~
[SDOI2011]染色(信息学奥赛一本通 1563)(洛谷 2486)
原文:https://www.cnblogs.com/ljy-endl/p/11375638.html