BZOJ2243: [SDOI2011]染色

2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 1934  Solved: 775
[Submit][Status]

Description

 

给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上所有点都染成颜色c

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“1122213段组成:“11、“222和“1

请你写一个程序依次完成这m个操作。

Input

第一行包含2个整数nm,分别表示节点数和操作数;

第二行包含n个正整数表示n个节点的初始颜色

下面 行每行包含两个整数xy,表示xy之间有一条无向边。

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

“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括ab)都染成颜色c

“Q a b”表示这是一个询问操作,询问节点a到节点b(包括ab)路径上的颜色段数量。

 

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

题解:
强大的树链剖分!强大的线段树!
原来统计一段序列被分为几段是可以分治的,一直想这个想了好久。。。
通过这题,学到了几点:
1.线段树
  pushdown操作是在查询到k,需要继续向下时调用
  pushup不管什么操作,完了之后调用一次
2.树链剖分
   确认算法没错肯定是哪儿犯了sb错误。。。
  现在感觉树链剖分也是蛮好写的,虽然代码蛮长
代码:
  1 {$M 10000000,0,maxlongint}
  2 const maxn=100000+100;
  3 type node1=record
  4      go,next:longint;
  5      end;
  6      node2=record
  7      l,r,lx,rx,num,mid,tag:longint;
  8      end;
  9 
 10 var  e:array[0..2*maxn] of node1;
 11      t:array[0..4*maxn] of node2;
 12      p,a,v,fa,s,head,dep,son,top:array[0..maxn] of longint;
 13      i,n,m,x,y,z,sz,ans,tot:longint;
 14      ch:char;
 15       procedure swap(var x,y:longint);
 16       var t:longint;
 17       begin
 18         t:=x;x:=y;y:=t;
 19       end;
 20      procedure insert(x,y:longint);
 21       begin
 22         inc(tot);
 23         e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
 24       end;
 25      function min(x,y:longint):longint;
 26       begin
 27         if x<y then exit(x) else exit(y);
 28       end;
 29      function max(x,y:longint):longint;
 30       begin
 31         if x>y then exit(x) else exit(y);
 32       end;
 33 procedure dfs1(x:longint);
 34  var i,j,y:longint;
 35  begin
 36    j:=0;s[x]:=1;
 37    i:=head[x];
 38    while i<>0 do
 39     begin
 40      y:=e[i].go;
 41      if dep[y]=0 then
 42        begin
 43          dep[y]:=dep[x]+1;
 44          fa[y]:=x;
 45          dfs1(y);
 46          inc(s[x],s[y]);
 47          if s[y]>s[j] then j:=y;
 48        end;
 49      i:=e[i].next;
 50     end;
 51    son[x]:=j;
 52  end;
 53 procedure dfs2(x,chain:longint);
 54  var i,y:longint;
 55  begin
 56    inc(sz);p[x]:=sz;top[x]:=chain;
 57    if son[x]<>0 then dfs2(son[x],chain);
 58    i:=head[x];
 59    while i<>0 do
 60      begin
 61       y:=e[i].go;
 62       if (y<>son[x]) and (y<>fa[x]) then dfs2(y,y);
 63       i:=e[i].next;
 64      end;
 65  end;
 66 procedure pushup(k:longint);
 67  begin
 68    with t[k] do
 69     begin
 70       num:=t[k<<1].num+t[k<<1+1].num-ord(t[k<<1].rx=t[k<<1+1].lx);
 71       lx:=t[k<<1].lx;rx:=t[k<<1+1].rx;
 72     end;
 73  end;
 74 
 75 procedure build(k,x,y:longint);
 76  begin
 77    with t[k] do
 78     begin
 79      l:=x;r:=y;mid:=(l+r)>>1;tag:=0;
 80      if l=r then begin lx:=a[l];rx:=a[l];num:=1;exit;end;
 81      build(k<<1,l,mid);build(k<<1+1,mid+1,r);
 82      pushup(k);
 83     end;
 84  end;
 85 
 86 procedure init;
 87  begin
 88    readln(n,m);
 89    for i:=1 to n do read(v[i]);readln;
 90    for i:=1 to n-1 do begin readln(x,y);insert(x,y);insert(y,x);end;
 91    dep[1]:=1;
 92    dfs1(1);
 93    dfs2(1,1);
 94    for i:=1 to n do a[p[i]]:=v[i];
 95    build(1,1,n);
 96  end;
 97 procedure same(k,val:longint);
 98  begin
 99    with t[k] do
100     begin
101      tag:=val;lx:=val;rx:=val;num:=1;
102     end;
103  end;
104 
105 procedure pushdown(k:longint);
106  begin
107    with t[k] do
108     begin
109      if (tag=0) or (l=r) then exit;
110      same(k<<1,tag);same(k<<1+1,tag);
111      tag:=0;
112     end;
113  end;
114 
115 procedure change(k,x,y,z:longint);
116  begin
117    with t[k] do
118     begin
119      pushdown(k);
120      if (l=x) and (r=y) then begin same(k,z);exit;end;
121      pushdown(k);
122      if y<=mid then change(k<<1,x,y,z)
123      else if x>mid then change(k<<1+1,x,y,z)
124      else
125        begin
126          change(k<<1,x,mid,z);
127          change(k<<1+1,mid+1,y,z);
128        end;
129      pushup(k);
130     end;
131  end;
132 function query(k,x,y:longint):longint;
133  begin
134    with t[k] do
135     begin
136      if (l=x) and (r=y) then exit(num);
137      pushdown(k);
138      if y<=mid then exit(query(k<<1,x,y))
139      else if x>mid then exit(query(k<<1+1,x,y))
140      else exit(query(k<<1,x,mid)+query(k<<1+1,mid+1,y)-ord(t[k<<1].rx=t[k<<1+1].lx));
141      pushup(k);
142     end;
143  end;
144 function get(k,x:longint):longint;
145  begin
146    with t[k] do
147     begin
148      if l=r then exit(lx);
149      pushdown(k);
150      if x<=mid then exit(get(k<<1,x)) else exit(get(k<<1+1,x));
151      pushup(k);
152     end;
153  end;
154 
155 procedure solvechange;
156  begin
157    readln(x,y,z);
158    while top[x]<>top[y] do
159      begin
160       if dep[top[x]]<dep[top[y]] then swap(x,y);
161       change(1,p[top[x]],p[x],z);
162       x:=fa[top[x]];
163      end;
164    if dep[x]>dep[y] then swap(x,y);
165    change(1,p[x],p[y],z);
166  end;
167 procedure getans;
168  begin
169    ans:=0;
170    readln(x,y);
171    while top[x]<>top[y] do
172      begin
173       if dep[top[x]]<dep[top[y]] then swap(x,y);
174       inc(ans,query(1,p[top[x]],p[x]));
175       dec(ans,ord(get(1,p[top[x]])=get(1,p[fa[top[x]]])));
176       x:=fa[top[x]];
177      end;
178    if dep[x]>dep[y] then swap(x,y);
179    inc(ans,query(1,p[x],p[y]));
180    writeln(ans);
181  end;
182 
183 procedure main;
184  begin
185    for i:=1 to m do
186     begin
187      read(ch);
188      if ch='C' then solvechange
189      else getans;
190     end;
191  end;
192 begin
193   assign(input,'input.txt');assign(output,'output.txt');
194   reset(input);rewrite(output);
195   init;
196   main;
197   close(input);close(output);
198 end.                           
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/3900051.html