又见bzoj的语言歧视,囧……
bzoj3083过了本地的数据在上面出现各种奇葩的TLE
835083 phile 3083 Time_Limit_Exceed 17092 kb 4872 ms Pascal/Edit 4931B 2015-01-11 19:53:32
10s的时限在逗我?
UPD:现在已经没有问题了……
这两道题目还是不错的
首先这道题是很像动态树的题目,我们发现树的形态不发生变化,而只是根在变化
考虑树链剖分,修改显然跟根的变化毫无关系
主要是查询,首先对于子树的查询肯定是dfs序(而轻重链剖分正是dfs序的一种特殊形式)
下面我们想,一次换跟操作对哪些点的查询会产生影响
画图可知,换根只会影响新根的祖先们的查询,如果不是祖先,那直接查询即可
而是祖先的话,设查询点x和新根路径上离x最近的那个点为y
显然,除去在原图上以y为根的子树,其余部分都应该是换根后的x的子树
由此题目得解,这里给出bzoj3083的代码
1 const inf=2147483647; 2 type node=record 3 po,next:longint; 4 end; 5 6 var c,e,b,a,d,p,size,top,fa:array[0..100010] of longint; 7 w:array[0..200010] of node; 8 tree,lazy:array[0..100010*4] of longint; 9 anc:array[0..100010,0..17] of longint; 10 root,ch,i,s,len,n,m,x,y,z:longint; 11 12 function min(a,b:longint):longint; 13 begin 14 if a>b then exit(b) else exit(a); 15 end; 16 17 procedure push(i:longint); 18 begin 19 lazy[i*2]:=lazy[i]; 20 lazy[i*2+1]:=lazy[i]; 21 tree[i*2]:=lazy[i]; 22 tree[i*2+1]:=lazy[i]; 23 lazy[i]:=0; 24 end; 25 26 procedure swap(var a,b:longint); 27 var c:longint; 28 begin 29 c:=a; 30 a:=b; 31 b:=c; 32 end; 33 34 procedure add(x,y:longint); 35 begin 36 inc(len); 37 w[len].po:=y; 38 w[len].next:=p[x]; 39 p[x]:=len; 40 end; 41 42 procedure dfs1(x:longint); 43 var i,y:longint; 44 begin 45 for i:=1 to s do 46 begin 47 y:=anc[x,i-1]; 48 if anc[y,i-1]=0 then break; 49 anc[x,i]:=anc[y,i-1]; 50 end; 51 size[x]:=1; 52 i:=p[x]; 53 while i<>0 do 54 begin 55 y:=w[i].po; 56 if fa[x]<>y then 57 begin 58 d[y]:=d[x]+1; 59 fa[y]:=x; 60 anc[y,0]:=x; 61 dfs1(y); 62 size[x]:=size[x]+size[y]; 63 end; 64 i:=w[i].next; 65 end; 66 end; 67 68 procedure dfs2(x:longint); 69 var q,i,y:longint; 70 begin 71 inc(len); 72 b[len]:=x; 73 c[x]:=len; 74 q:=0; 75 i:=p[x]; 76 while i<>0 do 77 begin 78 y:=w[i].po; 79 if fa[y]=x then 80 if size[y]>size[q] then q:=y; 81 i:=w[i].next; 82 end; 83 if q<>0 then 84 begin 85 top[q]:=top[x]; 86 dfs2(q); 87 end; 88 i:=p[x]; 89 while i<>0 do 90 begin 91 y:=w[i].po; 92 if (fa[y]=x) and (y<>q) then 93 begin 94 top[y]:=y; 95 dfs2(y); 96 end; 97 i:=w[i].next; 98 end; 99 e[x]:=len; //【c[x],e[x]】表示了以x根的子树所代表的区间 100 end; 101 102 procedure build(i,l,r:longint); 103 var m:longint; 104 begin 105 if l=r then tree[i]:=a[b[l]] 106 else begin 107 m:=(l+r) shr 1; 108 build(i*2,l,m); 109 build(i*2+1,m+1,r); 110 tree[i]:=min(tree[i*2],tree[i*2+1]); 111 end; 112 end; 113 114 procedure change(i,l,r,x,y:longint); 115 var m:longint; 116 begin 117 if (x<=l) and (y>=r) then 118 begin 119 lazy[i]:=z; 120 tree[i]:=z; 121 end 122 else begin 123 if lazy[i]<>0 then push(i); 124 m:=(l+r) shr 1; 125 if x<=m then change(i*2,l,m,x,y); 126 if y>m then change(i*2+1,m+1,r,x,y); 127 tree[i]:=min(tree[i*2],tree[i*2+1]); 128 end; 129 end; 130 131 procedure work(x,y:longint); 132 var f1,f2:longint; 133 begin 134 f1:=top[x]; 135 f2:=top[y]; 136 while f1<>f2 do 137 begin 138 if d[f1]>=d[f2] then 139 begin 140 change(1,1,n,c[f1],c[x]); 141 x:=fa[f1]; 142 end 143 else begin 144 change(1,1,n,c[f2],c[y]); 145 y:=fa[f2]; 146 end; 147 f1:=top[x]; 148 f2:=top[y]; 149 end; 150 if c[x]>c[y] then swap(x,y); 151 change(1,1,n,c[x],c[y]); 152 end; 153 154 function getans(i,l,r,x,y:longint):longint; 155 var m,s:longint; 156 begin 157 if x>y then exit(inf); 158 if (x<=l) and (y>=r) then exit(tree[i]) 159 else begin 160 if lazy[i]<>0 then push(i); 161 m:=(l+r) shr 1; 162 s:=inf; 163 if x<=m then s:=getans(i*2,l,m,x,y); 164 if y>m then s:=min(s,getans(i*2+1,m+1,r,x,y)); 165 exit(s); 166 end; 167 end; 168 169 function check(x,y:longint):boolean; 170 var i,k:longint; 171 begin 172 if d[y]>=d[x] then exit(false); 173 for i:=s downto 0 do 174 if d[x]-1 shl i>=d[y] then x:=anc[x,i]; 175 if x=y then exit(true) else exit(false); 176 end; 177 178 function ask(x:longint):longint; 179 var a,z,i:longint; 180 begin 181 if x=root then exit(tree[1]); 182 if not check(root,x) then exit(getans(1,1,n,c[x],e[x])) 183 else begin 184 z:=root; 185 for i:=s downto 0 do 186 if d[z]-1 shl i>d[x] then z:=anc[z,i]; //找最近点 187 a:=min(getans(1,1,n,1,c[z]-1),getans(1,1,n,e[z]+1,n)); 188 exit(a); 189 end; 190 end; 191 192 begin 193 readln(n,m); 194 for i:=1 to n-1 do 195 begin 196 readln(x,y); 197 add(x,y); 198 add(y,x); 199 end; 200 s:=trunc(ln(n)/ln(2)); 201 for i:=1 to n do 202 read(a[i]); 203 readln(root); 204 dfs1(root); 205 top[root]:=root; 206 len:=0; 207 dfs2(root); 208 build(1,1,n); 209 for i:=1 to m do 210 begin 211 read(ch); 212 if ch=1 then 213 begin 214 readln(x); 215 root:=x; 216 end 217 else if ch=2 then 218 begin 219 readln(x,y,z); 220 work(x,y); 221 end 222 else begin 223 readln(x); 224 writeln(ask(x)); 225 end; 226 end; 227 end.