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,表示xy之间有一条无向边。

下面 行每行描述一个操作:

“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

Sample Output

3

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.

 

posted @ 2017-02-25 15:21  Klaier  阅读(186)  评论(0编辑  收藏  举报