zoukankan      html  css  js  c++  java
  • bzoj3083 3306

    又见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


  • 相关阅读:
    [原创]java WEB学习笔记26:MVC案例完整实践(part 7)---修改的设计和实现
    [原创]java WEB学习笔记25:MVC案例完整实践(part 6)---新增操作的设计与实现
    [原创]java WEB学习笔记24:MVC案例完整实践(part 5)---删除操作的设计与实现
    [原创]java WEB学习笔记23:MVC案例完整实践(part 4)---模糊查询的设计与实现
    Tapestry IoC Configuration
    Tapestry IoC Decorator
    Tapestry IoC Service
    Tapestry-Again
    mysql error nr.1045 解决方法
    Bootstrap学习 导航
  • 原文地址:https://www.cnblogs.com/phile/p/4473030.html
Copyright © 2011-2022 走看看