首页 > 代码库 > [BZOJ 2243][SDOI2011] 染色
[BZOJ 2243][SDOI2011] 染色
可以说是树链剖分的模板题吧
基本思想就是先树链剖分,然后用线段树维护区间,区间的颜色种类个数,区间左端点的颜色,区间右端点的颜色
区间合并时,区间的颜色种类个数=左区间个数+右区间的个数,如果左区间的右端点的颜色等于右区间的左端点的颜色,答案还要减一
下面是代码:(用的是栈模拟递归)
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<iostream> 7 #define N 100100 8 #define M 200100 9 using namespace std; 10 11 int n,m,a,b,p; 12 int color[N],head[N],go[M],next[M]; 13 14 void build(int a,int b) 15 { 16 go[++p]=b; 17 next[p]=head[a]; 18 head[a]=p; 19 } 20 21 struct dfsdata 22 { 23 int a,i; 24 void newdata(int x,int y){a=x;i=y;} 25 }Stack[N]; 26 27 struct makedata 28 { 29 int a,i,yes; 30 void newdata(int x,int y,int z=1){a=x;i=y;yes=z;} 31 }S[N]; 32 33 int tail,f[N],size[N],max_son[N],u,v,deep[N]; 34 35 void dfs() 36 { 37 int i; 38 Stack[tail=1].newdata(1,head[1]);f[1]=0;size[1]=1;deep[1]=1; 39 while (tail) 40 { 41 i=Stack[tail].i;v=Stack[tail].a; 42 if (!i) 43 { 44 size[f[v]]+=size[v]; 45 if (size[v]>size[max_son[f[v]]]) max_son[f[v]]=v; 46 tail--; 47 continue; 48 } 49 u=go[i]; 50 Stack[tail].i=next[i]; 51 if (f[v]!=u) 52 { 53 size[u]=1; 54 f[u]=v; 55 deep[u]=deep[v]+1; 56 Stack[++tail].newdata(u,head[u]); 57 } 58 } 59 } 60 61 int L[N],l_deep[N],top[N],len,que[N]; 62 63 void make() 64 { 65 int i; 66 S[tail=1].newdata(1,head[1]);L[1]=len=1;l_deep[1]=1;top[1]=1;que[1]=1; 67 while (tail) 68 { 69 v=S[tail].a;i=S[tail].i; 70 if (!i || size[v]==1){tail--;continue;} 71 if (S[tail].yes) 72 { 73 S[tail].yes=0; 74 u=max_son[v]; 75 L[u]=++len; 76 que[len]=u; 77 l_deep[u]=l_deep[v]; 78 top[u]=top[v]; 79 S[++tail].newdata(u,head[u]); 80 continue; 81 } 82 u=go[i]; 83 S[tail].i=next[i]; 84 if (u!=f[v] && u!=max_son[v]) 85 { 86 L[u]=++len; 87 que[len]=u; 88 l_deep[u]=l_deep[v]+1; 89 top[u]=u; 90 S[++tail].newdata(u,head[u]); 91 } 92 } 93 } 94 95 //==========================SegmentTree===========================// 96 int tree[N<<2],SL[N<<2],SR[N<<2],LZ[N<<2],lazy[N<<2]; 97 98 void update(int a) 99 {100 tree[a]=tree[a<<1]+tree[(a<<1)+1];101 SL[a]=SL[a<<1];SR[a]=SR[(a<<1)+1];102 if (SR[a<<1]==SL[(a<<1)+1]) tree[a]--;103 }104 105 void BuildTree(int p,int l,int r)106 {107 if (l==r)108 {109 tree[p]=1;110 SL[p]=SR[p]=color[que[l]];111 return;112 }113 int mid=(l+r)>>1;114 BuildTree(p<<1,l,mid);115 BuildTree((p<<1)+1,mid+1,r);116 update(p);117 }118 119 void Push_down(int a)120 {121 if (!LZ[a]) return;122 LZ[a]=0;123 LZ[a<<1]=LZ[(a<<1)+1]=1;124 lazy[a<<1]=lazy[(a<<1)+1]=lazy[a];125 SL[a<<1]=SR[a<<1]=SL[(a<<1)+1]=SR[(a<<1)+1]=lazy[a];126 tree[a]=tree[a<<1]=tree[(a<<1)+1]=1;127 }128 129 void Change(int p,int l,int r,int fl,int fr,int c)130 {131 if (fl<=l&&r<=fr)132 {133 LZ[p]=1;134 lazy[p]=c;135 SL[p]=SR[p]=c;136 tree[p]=1;137 return;138 }139 Push_down(p);140 int mid=(l+r)>>1;141 if (fl<=mid) Change(p<<1,l,mid,fl,fr,c);142 if (fr>mid) Change((p<<1)+1,mid+1,r,fl,fr,c);143 update(p);144 }145 146 int Query(int p,int l,int r,int fl,int fr,int al,int &x,int ar,int &y)147 {148 if (l==fl&&r==fr)149 {150 if (LZ[p])151 {152 if (l==r)153 {154 LZ[p]=0;155 tree[p]=1;156 SL[p]=SR[p]=lazy[p];157 }158 else Push_down(p),update(p);159 }160 if (l==al) x=SL[p];161 if (r==ar) y=SR[p];162 return tree[p];163 }164 Push_down(p);165 int mid=(l+r)>>1;166 if (fr<=mid) return Query(p<<1,l,mid,fl,fr,al,x,ar,y);167 if (fl>mid) return Query((p<<1)+1,mid+1,r,fl,fr,al,x,ar,y);168 int ans=Query(p<<1,l,mid,fl,mid,al,x,ar,y)+Query((p<<1)+1,mid+1,r,mid+1,fr,al,x,ar,y);169 if (SR[p<<1]==SL[(p<<1)+1]) ans--;170 return ans;171 }172 //==========================SegmentTree===========================//173 174 void Change(int a,int b,int c)175 {176 while (top[a]!=top[b])177 {178 if (l_deep[a]<l_deep[b]) swap(a,b);179 color[a]=c;180 if (top[a]!=a)181 {182 Change(1,1,n,L[top[a]],L[a],c);183 a=top[a];184 }185 else186 {187 Change(1,1,n,L[a],L[a],c);188 a=f[a];189 }190 }191 color[a]=color[b]=c;192 if (L[a]>L[b]) swap(a,b);193 Change(1,1,n,L[a],L[b],c);194 }195 196 void Query(int a,int b)197 {198 int ans=0,ac=-1,bc=-1,x,y;199 if (a==b)200 {201 printf("1\n");202 return;203 }204 while (top[a]!=top[b])205 {206 if (l_deep[a]<l_deep[b]) swap(a,b),swap(ac,bc);207 if (top[a]!=a)208 {209 ans+=Query(1,1,n,L[top[a]]+1,L[a],L[top[a]]+1,x,L[a],y);210 if (y==ac) ans--;211 ac=x;212 a=top[a];213 }214 else215 {216 ans+=Query(1,1,n,L[a],L[a],L[a],x,L[a],y);217 if (y==ac) ans--;218 ac=x;219 a=f[a];220 }221 }222 if (L[a]>L[b]) swap(a,b),swap(ac,bc);223 ans+=Query(1,1,n,L[a],L[b],L[a],x,L[b],y);224 if (x==ac) ans--;225 if (y==bc) ans--;226 printf("%d\n",ans);227 }228 229 int main()230 {231 scanf("%d%d",&n,&m);232 for (int i=1;i<=n;i++) scanf("%d",color+i);233 for (int i=1;i<n;i++)234 {235 scanf("%d%d\n",&a,&b);236 build(a,b);237 build(b,a);238 }239 dfs();240 make();241 BuildTree(1,1,n);242 for (int i=1;i<=m;i++)243 {244 char ch;int c;245 scanf("%c",&ch);246 if (ch==‘C‘)247 {248 scanf("%d%d%d\n",&a,&b,&c);249 Change(a,b,c);250 }251 else252 {253 scanf("%d%d\n",&a,&b);254 Query(a,b);255 }256 }257 return 0;258 }
[BZOJ 2243][SDOI2011] 染色
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。