首页 > 代码库 > 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
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
2
3
4
HINT
对于另外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 遥远的国度