bzoj2243[SDOI2011]染色
Description
给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
Input
第一行包含2个整数n和m,分别表示节点数和操作数;
第二行包含n个正整数表示n个节点的初始颜色
下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。
下面 行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。
Output
对于每个询问操作,输出一行答案。
Sample Input
6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
Sample Output
3
1
2
1
2
HINT
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
Source
第一轮day1
这题不是很难,直接树链剖分,然后用线段树维护一下,线段树结点要记录区间左端点颜色和区间右端点颜色,这样才好对区间信息进行合并。另外要注意的是如果两条链交界处的两个点颜色相同,就要将ans减1。
1 program rrr(input,output); 2 type 3 edgetype=record 4 t,next:longint; 5 end; 6 treetype=record 7 l,r,lc,rc,s,d:longint; 8 end; 9 var 10 e:array[0..200020]of edgetype; 11 a:array[0..400040]of treetype; 12 b,c0,c,dep,q,siz,idx,belong,head,fa:array[0..100010]of longint; 13 n,m,i,x,y,z,cnt,tot,h,t:longint; 14 ch:char; 15 procedure add(x,y:longint); 16 begin 17 inc(cnt);e[cnt].t:=y;e[cnt].next:=b[x];b[x]:=cnt; 18 end; 19 procedure bfs; 20 begin 21 fillchar(dep,sizeof(dep),0); 22 h:=0;t:=1;q[1]:=1;dep[1]:=1; 23 while h<t do 24 begin 25 inc(h);i:=b[q[h]]; 26 while i<>0 do 27 begin 28 if dep[e[i].t]=0 then 29 begin 30 fa[e[i].t]:=q[h];dep[e[i].t]:=dep[q[h]]+1; 31 inc(t);q[t]:=e[i].t; 32 end; 33 i:=e[i].next; 34 end; 35 end; 36 for i:=1 to n do siz[i]:=1; 37 for i:=n downto 2 do inc(siz[fa[q[i]]],siz[q[i]]); 38 end; 39 procedure dfs(k:longint); 40 var 41 i,j,max:longint; 42 begin 43 if siz[k]=1 then exit; 44 j:=b[k];max:=0; 45 while j<>0 do 46 begin 47 if e[j].t<>fa[k] then if siz[e[j].t]>max then begin max:=siz[e[j].t];i:=e[j].t; end; 48 j:=e[j].next; 49 end; 50 belong[i]:=belong[k];inc(cnt);idx[i]:=cnt; 51 dfs(i); 52 if siz[k]=2 then exit; 53 j:=b[k]; 54 while j<>0 do 55 begin 56 if (e[j].t<>fa[k]) and (e[j].t<>i) then 57 begin 58 inc(tot);belong[e[j].t]:=tot;head[tot]:=e[j].t; 59 inc(cnt);idx[e[j].t]:=cnt; 60 dfs(e[j].t); 61 end; 62 j:=e[j].next; 63 end; 64 end; 65 procedure build(k,l,r:longint); 66 var 67 i,mid:longint; 68 begin 69 a[k].l:=l;a[k].r:=r;a[k].d:=0; 70 if l=r then begin a[k].lc:=c[l];a[k].rc:=c[l];a[k].s:=1;exit; end; 71 mid:=(l+r)>>1;i:=k<<1; 72 build(i,l,mid); 73 build(i+1,mid+1,r); 74 a[k].lc:=a[i].lc;a[k].rc:=a[i+1].rc; 75 a[k].s:=a[i].s+a[i+1].s;if a[i].rc=a[i+1].lc then dec(a[k].s); 76 end; 77 procedure pushdown(k:longint); 78 var 79 i:longint; 80 begin 81 if a[k].d=0 then exit; 82 if a[k].l=a[k].r then begin a[k].d:=0;exit; end; 83 i:=k<<1;a[i].d:=a[k].d;a[i].s:=1;a[i].lc:=a[k].d;a[i].rc:=a[k].d; 84 inc(i);a[i].d:=a[k].d;a[i].s:=1;a[i].lc:=a[k].d;a[i].rc:=a[k].d; 85 a[k].d:=0; 86 end; 87 procedure change(k,x,y:longint); 88 var 89 mid,i:longint; 90 begin 91 pushdown(k); 92 if (x<=a[k].l) and (a[k].r<=y) then begin a[k].d:=z;a[k].lc:=z;a[k].rc:=z;a[k].s:=1;exit; end; 93 mid:=(a[k].l+a[k].r)>>1;i:=k<<1; 94 if x<=mid then change(i,x,y); 95 if mid<y then change(i+1,x,y); 96 a[k].lc:=a[i].lc;a[k].rc:=a[i+1].rc; 97 if a[i].rc=a[i+1].lc then a[k].s:=a[i].s+a[i+1].s-1 else a[k].s:=a[i].s+a[i+1].s; 98 end; 99 function ask(k,x,y:longint):longint; 100 var 101 mid,i,ans:longint; 102 begin 103 pushdown(k); 104 if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].s); 105 mid:=(a[k].l+a[k].r)>>1;i:=k<<1;ans:=0; 106 if x<=mid then ans:=ask(i,x,y); 107 if mid<y then ans:=ans+ask(i+1,x,y); 108 if (x<=mid) and (mid<y) then if a[i].rc=a[i+1].lc then dec(ans); 109 exit(ans); 110 end; 111 function askc(k,x:longint):longint; 112 var 113 mid:longint; 114 begin 115 pushdown(k); 116 if a[k].l=a[k].r then exit(a[k].lc); 117 mid:=(a[k].l+a[k].r)>>1; 118 if x<=mid then exit(askc(k<<1,x)) else exit(askc(k<<1+1,x)); 119 end; 120 procedure cange; 121 begin 122 while belong[x]<>belong[y] do 123 if dep[head[belong[x]]]>dep[head[belong[y]]] then 124 begin change(1,idx[head[belong[x]]],idx[x]);x:=fa[head[belong[x]]]; end 125 else begin change(1,idx[head[belong[y]]],idx[y]);y:=fa[head[belong[y]]]; end; 126 if dep[x]<dep[y] then change(1,idx[x],idx[y]) else change(1,idx[y],idx[x]); 127 end; 128 function query:longint; 129 var 130 ans:longint; 131 begin 132 ans:=0; 133 while belong[x]<>belong[y] do 134 if dep[head[belong[x]]]>dep[head[belong[y]]] then 135 begin inc(ans,ask(1,idx[head[belong[x]]],idx[x]));x:=head[belong[x]];if askc(1,idx[x])=askc(1,idx[fa[x]]) then dec(ans);x:=fa[x] end 136 else begin inc(ans,ask(1,idx[head[belong[y]]],idx[y]));y:=head[belong[y]];if askc(1,idx[y])=askc(1,idx[fa[y]]) then dec(ans);y:=fa[y] end; 137 if dep[x]<dep[y] then inc(ans,ask(1,idx[x],idx[y])) else inc(ans,ask(1,idx[y],idx[x])); 138 exit(ans); 139 end; 140 begin 141 assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output); 142 readln(n,m); 143 for i:=1 to n do read(c0[i]); 144 fillchar(b,sizeof(b),0);cnt:=0; 145 for i:=2 to n do begin readln(x,y);add(x,y);add(y,x); end; 146 bfs; 147 idx[1]:=1;cnt:=1;belong[1]:=1;tot:=1;head[1]:=1; 148 dfs(1); 149 for i:=1 to n do c[idx[i]]:=c0[i]; 150 build(1,1,n); 151 for i:=1 to m do 152 begin 153 read(ch,x,y); 154 if ch='C' then begin read(z);cange; end 155 else writeln(query); 156 readln; 157 end; 158 close(input);close(output); 159 end.