BZOJ2243染色(树链剖分)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ2243染色(树链剖分)相关的知识,希望对你有一定的参考价值。
题意:
给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
思路:树上的路径染色问题可以用树剖解决。
对于线段树的某个节点我们记录以下信息:最左端颜色,最右端颜色,整段中段数,以及lazytag。
其中lazytag>=0时表示该区间要改成什么颜色,-1表示当前节点没有标记。
转换到树上做即可
BZOJ过了样例就一遍过(萎靡)
1 type un=record 2 l,r,s,tag:longint; 3 end; 4 var t:array[1..500000]of un; 5 f:array[1..110000,0..18]of longint; 6 head,vet,next,flag,dep,fa,top, 7 tid,id,size,son,a:array[1..210000]of longint; 8 n,m,i,j,k,x,y,z,q,tot,time:longint; 9 ch:string; 10 emp:un; 11 12 procedure swap(var x,y:longint); 13 var t:longint; 14 begin 15 t:=x; x:=y; y:=t; 16 end; 17 18 procedure add(a,b:longint); 19 begin 20 inc(tot); 21 next[tot]:=head[a]; 22 vet[tot]:=b; 23 head[a]:=tot; 24 end; 25 26 procedure dfs1(u:longint); 27 var e,v,maxsize,i:longint; 28 begin 29 flag[u]:=1; size[u]:=1; maxsize:=0; son[u]:=0; 30 for i:=1 to 18 do 31 begin 32 if dep[u]<(1<<i) then break; 33 f[u,i]:=f[f[u,i-1],i-1]; 34 end; 35 36 e:=head[u]; 37 while e<>0 do 38 begin 39 v:=vet[e]; 40 if flag[v]=0 then 41 begin 42 dep[v]:=dep[u]+1; 43 f[v,0]:=u; 44 fa[v]:=u; 45 dfs1(v); 46 size[u]:=size[u]+size[v]; 47 if size[v]>maxsize then 48 begin 49 maxsize:=size[v]; 50 son[u]:=v; 51 end; 52 end; 53 e:=next[e]; 54 end; 55 end; 56 57 procedure dfs2(u,ance:longint); 58 var e,v:longint; 59 begin 60 flag[u]:=1; inc(time); tid[u]:=time; id[time]:=u; top[u]:=ance; 61 if son[u]>0 then dfs2(son[u],ance); 62 e:=head[u]; 63 while e<>0 do 64 begin 65 v:=vet[e]; 66 if flag[v]=0 then dfs2(v,v); 67 e:=next[e]; 68 end; 69 end; 70 71 function lca(x,y:longint):longint; 72 var i,d:longint; 73 begin 74 if dep[x]<dep[y] then swap(x,y); 75 d:=dep[x]-dep[y]; 76 for i:=0 to 18 do 77 if d and (1<<i)>0 then x:=f[x,i]; 78 for i:=18 downto 0 do 79 if f[x,i]<>f[y,i] then 80 begin 81 x:=f[x,i]; y:=f[y,i]; 82 end; 83 if x=y then exit(x); 84 exit(f[x,0]); 85 end; 86 87 procedure pushup(p:longint); 88 begin 89 t[p].l:=t[p<<1].l; t[p].r:=t[p<<1+1].r; 90 if t[p<<1].r<>t[p<<1+1].l then t[p].s:=t[p<<1].s+t[p<<1+1].s 91 else t[p].s:=t[p<<1].s+t[p<<1+1].s-1; 92 end; 93 94 procedure pushdown(p,l,r:longint); 95 var tmp:longint; 96 begin 97 tmp:=t[p].tag; t[p].tag:=-1; 98 if (tmp=-1)or(l=r) then exit; 99 t[p<<1].s:=1; t[p<<1+1].s:=1; 100 t[p<<1].tag:=tmp; t[p<<1+1].tag:=tmp; 101 t[p<<1].l:=tmp; t[p<<1].r:=tmp; 102 t[p<<1+1].l:=tmp; t[p<<1+1].r:=tmp; 103 end; 104 105 procedure build(l,r,p:longint); 106 var mid:longint; 107 begin 108 if l=r then 109 begin 110 t[p].s:=1; 111 t[p].tag:=-1; 112 exit; 113 end; 114 t[p].tag:=-1; 115 mid:=(l+r)>>1; 116 build(l,mid,p<<1); 117 build(mid+1,r,p<<1+1); 118 end; 119 120 procedure update(l,r,x,y,v,p:longint); 121 var mid:longint; 122 begin 123 pushdown(p,l,r); 124 if (l>=x)and(r<=y) then 125 begin 126 t[p].l:=v; t[p].r:=v; 127 t[p].s:=1; t[p].tag:=v; 128 exit; 129 end; 130 mid:=(l+r)>>1; 131 if x<=mid then update(l,mid,x,y,v,p<<1); 132 if y>mid then update(mid+1,r,x,y,v,p<<1+1); 133 pushup(p); 134 end; 135 136 function query(l,r,x,y,p:longint):longint; 137 var mid,t1,t2:longint; 138 begin 139 pushdown(p,l,r); 140 if (l>=x)and(r<=y) then exit(t[p].s); 141 mid:=(l+r)>>1; 142 t1:=0; t2:=0; 143 if x<=mid then t1:=query(l,mid,x,y,p<<1); 144 if y>mid then t2:=query(mid+1,r,x,y,p<<1+1); 145 if t1=0 then exit(t2); 146 if t2=0 then exit(t1); 147 query:=t1+t2; 148 if t[p<<1].r=t[p<<1+1].l then dec(query); 149 end; 150 151 function get(l,r,x,p:longint):longint; 152 var mid:longint; 153 begin 154 pushdown(p,l,r); 155 if (l=x)and(r=x) then exit(t[p].l); 156 mid:=(l+r)>>1; 157 if x<=mid then exit(get(l,mid,x,p<<1)) 158 else exit(get(mid+1,r,x,p<<1+1)); 159 end; 160 161 function ask(x,y:longint):longint; 162 var q:longint; 163 begin 164 q:=lca(x,y); 165 ask:=0; 166 while top[x]<>top[q] do 167 begin 168 ask:=ask+query(1,n,tid[top[x]],tid[x],1); 169 if get(1,n,tid[top[x]],1)=get(1,n,tid[fa[top[x]]],1) then dec(ask); 170 x:=fa[top[x]]; 171 end; 172 ask:=ask+query(1,n,tid[q],tid[x],1); 173 while top[y]<>top[q] do 174 begin 175 ask:=ask+query(1,n,tid[top[y]],tid[y],1); 176 if get(1,n,tid[top[y]],1)=get(1,n,tid[fa[top[y]]],1) then dec(ask); 177 y:=fa[top[y]]; 178 end; 179 ask:=ask+query(1,n,tid[q],tid[y],1); 180 dec(ask); 181 182 end; 183 184 procedure solve(x,y,z:longint); 185 var q:longint; 186 begin 187 q:=lca(x,y); 188 while top[x]<>top[q] do 189 begin 190 update(1,n,tid[top[x]],tid[x],z,1); 191 x:=fa[top[x]]; 192 end; 193 update(1,n,tid[q],tid[x],z,1); 194 while top[y]<>top[q] do 195 begin 196 update(1,n,tid[top[y]],tid[y],z,1); 197 y:=fa[top[y]]; 198 end; 199 update(1,n,tid[q],tid[y],z,1); 200 end; 201 202 begin 203 assign(input,‘bzoj2243.in‘); reset(input); 204 assign(output,‘bzoj2243.out‘); rewrite(output); 205 readln(n,m); 206 for i:=1 to n do read(a[i]); 207 for i:=1 to n-1 do 208 begin 209 readln(x,y); 210 add(x,y); 211 add(y,x); 212 end; 213 dfs1(1); 214 fillchar(flag,sizeof(flag),0); 215 dfs2(1,1); 216 build(1,n,1); 217 for i:=1 to n do update(1,n,tid[i],tid[i],a[i],1); 218 //for i:=1 to n do write(a[id[i]],‘ ‘); 219 for i:=1 to m do 220 begin 221 readln(ch); 222 x:=0; y:=0; z:=0; 223 case ch[1] of 224 ‘C‘: 225 begin 226 for k:=3 to length(ch) do 227 begin 228 if ch[k]=‘ ‘ then break; 229 x:=x*10+ord(ch[k])-ord(‘0‘); 230 end; 231 j:=k+1; 232 for k:=j to length(ch) do 233 begin 234 if ch[k]=‘ ‘ then break; 235 y:=y*10+ord(ch[k])-ord(‘0‘); 236 end; 237 j:=k+1; 238 for k:=j to length(ch) do z:=z*10+ord(ch[k])-ord(‘0‘); 239 solve(x,y,z); 240 end; 241 242 ‘Q‘: 243 begin 244 for k:=3 to length(ch) do 245 begin 246 if ch[k]=‘ ‘ then break; 247 x:=x*10+ord(ch[k])-ord(‘0‘); 248 end; 249 j:=k+1; 250 for k:=j to length(ch) do y:=y*10+ord(ch[k])-ord(‘0‘); 251 writeln(ask(x,y)); 252 end; 253 end; 254 end; 255 close(input); 256 close(output); 257 end.
以上是关于BZOJ2243染色(树链剖分)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 2243 2243: [SDOI2011]染色 树链剖分
bzoj2243: [SDOI2011]染色--线段树+树链剖分