又见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.
View Code

 


 

posted on 2015-01-16 22:42  acphile  阅读(152)  评论(0编辑  收藏  举报