首页 > 代码库 > bzoj3083 遥远的国度

bzoj3083 遥远的国度

Description

zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度。当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn完成任务后才能进入遥远的国度继续追杀。

问题是这样的:遥远的国度有n个城市,这些城市之间由一些路连接且这些城市构成了一颗树。这个国度有一个首都,我们可以把这个首都看做整棵树的根,但遥远的国度比较奇怪,首都是随时有可能变为另外一个城市的。遥远的国度的每个城市有一个防御值,有些时候RapiD会使得某两个城市之间的路径上的所有城市的防御值都变为某个值。RapiD想知道在某个时候,如果把首都看做整棵树的根的话,那么以某个城市为根的子树的所有城市的防御值最小是多少。由于RapiD无法解决这个问题,所以他拦住了zcwwzdjn希望他能帮忙。但zcwwzdjn还要追杀sb的zhx,所以这个重大的问题就被转交到了你的手上。

 

Input

第1行两个整数n m,代表城市个数和操作数。
第2行至第n行,每行两个整数 u v,代表城市u和城市v之间有一条路。
第n+1行,有n个整数,代表所有点的初始防御值。
第n+2行一个整数 id,代表初始的首都为id。
第n+3行至第n+m+2行,首先有一个整数opt,如果opt=1,接下来有一个整数id,代表把首都修改为id;如果opt=2,接下来有三个整数p1 p2 v,代表将p1 p2路径上的所有城市的防御值修改为v;如果opt=3,接下来有一个整数 id,代表询问以城市id为根的子树中的最小防御值。

Output


对于每个opt=3的操作,输出一行代表对应子树的最小点权值。

Sample Input

3 7
1 2
1 3
1 2 3
1
3 1
2 1 1 6
3 1
2 2 2 5
3 1
2 3 3 4
3 1

Sample Output

1
2
3
4

HINT

 对于20%的数据,n<=1000 m<=1000。
对于另外10%的数据,n<=100000,m<=100000,保证修改为单点修改。
对于另外10%的数据,n<=100000,m<=100000,保证树为一条链。
对于另外10%的数据,n<=100000,m<=100000,没有修改首都的操作。
对于100%的数据,n<=100000,m<=100000,0<所有权值<=2^31。

Source

zhonghaoxi提供

 

 

分类讨论之后还是可以树链剖分的,不是很难想。

写树链剖分的时候还错了一次,dfs的时候要判断不能再往一个点的父亲dfs(这个错误果然很sb)。

  1 program rrr(input,output);
  2 type
  3   etype=record
  4      t,next:longint;
  5   end;
  6   treetype=record
  7      l,r,min,d:longint;
  8   end;
  9 var
 10   a:array[0..400040]of treetype;
 11   e:array[0..200020]of etype;
 12   father:array[0..100010,0..17]of longint;
 13   b,c,q,dep,siz,son,ss,head,idx:array[0..100010]of longint;
 14   n,m,op,i,j,k,x,y,z,cnt,cap,h,t:longint;
 15 function min(a,b:longint):longint;
 16 begin
 17    if a<b then exit(a) else exit(b);
 18 end;
 19 procedure add(x,y:longint);
 20 begin
 21    inc(cnt);e[cnt].t:=y;e[cnt].next:=c[x];c[x]:=cnt;
 22 end;
 23 procedure dfs(k:longint);
 24 var
 25   i:longint;
 26 begin
 27    if son[k]=0 then exit;
 28    head[son[k]]:=head[k];inc(cnt);idx[son[k]]:=cnt;
 29    dfs(son[k]);
 30    i:=c[k];
 31    while i<>0 do
 32       begin
 33          if (e[i].t<>son[k]) and (e[i].t<>father[k,0]) then
 34             begin
 35                inc(cnt);idx[e[i].t]:=cnt;head[e[i].t]:=e[i].t;
 36                dfs(e[i].t);
 37             end;
 38          i:=e[i].next;
 39       end;
 40 end;
 41 procedure split;
 42 begin
 43    h:=0;t:=1;q[1]:=1;father[1,0]:=0;dep[1]:=1;
 44    while h<t do
 45       begin
 46          inc(h);i:=c[q[h]];
 47          while i<>0 do
 48             begin
 49                if e[i].t<>father[q[h],0] then
 50                   begin
 51                      father[e[i].t,0]:=q[h];dep[e[i].t]:=dep[q[h]]+1;
 52                      inc(t);q[t]:=e[i].t;
 53                   end;
 54                i:=e[i].next;
 55             end;
 56       end;
 57    fillchar(son,sizeof(son),0);fillchar(ss,sizeof(ss),0);
 58    for i:=1 to n do siz[i]:=1;
 59    for i:=n downto 1 do
 60       begin
 61          inc(siz[father[q[i],0]],siz[q[i]]);
 62          if siz[q[i]]>ss[father[q[i],0]] then begin ss[father[q[i],0]]:=siz[q[i]];son[father[q[i],0]]:=q[i]; end;
 63       end;
 64    for j:=1 to 16 do for i:=1 to n do father[i,j]:=father[father[i,j-1],j-1];
 65    cnt:=1;idx[1]:=1;head[1]:=1;
 66    dfs(1);
 67 end;
 68 procedure build(k,l,r:longint);
 69 var
 70   mid,i:longint;
 71 begin
 72    a[k].l:=l;a[k].r:=r;a[k].d:=0;
 73    if l=r then begin a[k].min:=b[l];exit; end;
 74    mid:=(l+r)>>1;i:=k+k;
 75    build(i,l,mid);build(i+1,mid+1,r);
 76    a[k].min:=min(a[i].min,a[i+1].min);
 77 end;
 78 procedure pushdown(k:longint);
 79 var
 80   i:longint;
 81 begin
 82    if a[k].l=a[k].r then a[k].d:=0;
 83    if a[k].d=0 then exit;
 84    i:=k+k;a[i].min:=a[k].d;a[i].d:=a[k].d;
 85    inc(i);a[i].min:=a[k].d;a[i].d:=a[k].d;
 86    a[k].d:=0;
 87 end;
 88 procedure change(k,x,y:longint);
 89 var
 90   mid,i:longint;
 91 begin
 92    pushdown(k);
 93    if (x<=a[k].l) and (a[k].r<=y) then begin a[k].min:=z;a[k].d:=z;exit; end;
 94    mid:=(a[k].l+a[k].r)>>1;i:=k+k;
 95    if x<=mid then change(i,x,y);
 96    if mid<y then change(i+1,x,y);
 97    a[k].min:=min(a[i].min,a[i+1].min);
 98 end;
 99 function ask(k,x,y:longint):longint;
100 var
101   mid,ans:longint;
102 begin
103    pushdown(k);
104    if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].min);
105    mid:=(a[k].l+a[k].r)>>1;ans:=maxlongint;
106    if x<=mid then ans:=ask(k+k,x,y);
107    if mid<y then ans:=min(ans,ask(k+k+1,x,y));
108    exit(ans);
109 end;
110 function cal(x,d:longint):longint;
111 begin
112    if dep[x]<d then exit(0);
113    for k:=16 downto 0 do if dep[father[x,k]]>=d then x:=father[x,k];
114    exit(x);
115 end;
116 procedure changee;
117 begin
118    while head[x]<>head[y] do
119       if dep[head[x]]>dep[head[y]] then begin change(1,idx[head[x]],idx[x]);x:=father[head[x],0]; end
120       else begin change(1,idx[head[y]],idx[y]);y:=father[head[y],0]; end;
121    if idx[x]<idx[y] then change(1,idx[x],idx[y]) else change(1,idx[y],idx[x]);
122 end;
123 function query:longint;
124 begin
125    if cap=x then exit(a[1].min);
126    if cal(cap,dep[x])=x then
127       begin
128          t:=cal(cap,dep[x]+1);
129          if idx[t]+siz[t]>n then exit(ask(1,1,idx[t]-1))
130          else exit(min(ask(1,1,idx[t]-1),ask(1,idx[t]+siz[t],n)));
131       end
132    else exit(ask(1,idx[x],idx[x]+siz[x]-1));
133 end;
134 begin
135    assign(input,r.in);assign(output,r.out);reset(input);rewrite(output);
136    readln(n,m);
137    fillchar(c,sizeof(c),0);cnt:=0;
138    for i:=1 to n-1 do begin readln(x,y);add(x,y);add(y,x); end;
139    split;
140    for i:=1 to n do read(b[idx[i]]);
141    build(1,1,n);
142    readln(cap);
143    for i:=1 to m do
144       begin
145         read(op,x);
146         if op=1 then cap:=x
147         else if op=2 then begin readln(y,z);changee; end
148         else if op=3 then writeln(query);
149       end;
150    close(input);close(output);
151 end.

 

bzoj3083 遥远的国度