您的位置:首页 > 其它

【BZOJ2243】染色(树链剖分)

2016-11-29 20:51 330 查看

题意:

给定一棵有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

.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.

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: