BZOJ2243: [SDOI2011]染色
2243: [SDOI2011]染色
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1934 Solved: 775
[Submit][Status]
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
题解:
强大的树链剖分!强大的线段树!
原来统计一段序列被分为几段是可以分治的,一直想这个想了好久。。。
通过这题,学到了几点:
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.