zoukankan      html  css  js  c++  java
  • bzoj2631 3282

    这两题都是link cut tree的裸题
    之前看Qtree的论文,只会在确定父子关系的情况下连边和删边
    如果在任意两个点连边删边怎么做呢?
    这时候我们不能随意的将一个点的父节点设为另一个点,因为其中某个点的父节点可能已经被设为另外某点了
    其实很简单,连边的时候,我们只要把x变成其所在原树的根,这样x是没有父节点了
    然后把x的父节点设为y即可,删边、询问路径的道理类似,具体见程序
    给出的是bzoj2631的程序

      1 const mo=51061;
      2 
      3 var fa,q,a,mul,add,size,sum:array[0..100010] of longint;
      4     rev:array[0..100010] of boolean;
      5     son:array[0..100010,1..2] of longint;
      6     i,x0,y0,x,y,z,n,m,t:longint;
      7     ch:char;
      8 
      9 function root(x:longint):boolean;  //判断是Auxiliary tree(splay)上的父节点还是path parent
     10   begin
     11     exit((son[fa[x],1]<>x) and (son[fa[x],2]<>x));
     12   end;
     13 
     14 procedure swap(var a,b:longint);
     15   var c:longint;
     16   begin
     17     c:=a;
     18     a:=b;
     19     b:=c;
     20   end;
     21 
     22 procedure update(x:longint);
     23   var l,r:longint;
     24   begin
     25     l:=son[x,1];
     26     r:=son[x,2];
     27     size[x]:=(size[l]+size[r]+1) mod mo;
     28     sum[x]:=(a[x]+sum[l]+sum[r]) mod mo;
     29   end;
     30 
     31 procedure calc(x,c,j:longint);
     32   begin
     33     if (c<=42000) then  //常数优化,少用int64
     34     begin
     35       mul[x]:=mul[x]*c mod mo;
     36       add[x]:=(add[x]*c+j) mod mo;
     37       sum[x]:=(sum[x]*c+int64(j)*int64(size[x])) mod mo;
     38       a[x]:=(a[x]*c+j) mod mo;
     39     end
     40     else begin
     41       mul[x]:=int64(mul[x])*int64(c) mod mo;
     42       add[x]:=(int64(add[x])*int64(c)+j) mod mo;
     43       sum[x]:=(int64(sum[x])*int64(c)+int64(j)*int64(size[x])) mod mo;
     44       a[x]:=(int64(a[x])*int64(c)+j) mod mo;
     45     end;
     46   end;
     47 
     48 
     49 procedure push(x:longint);
     50   begin
     51     if rev[x] then
     52     begin
     53       rev[son[x,1]]:=not rev[son[x,1]];
     54       rev[son[x,2]]:=not rev[son[x,2]];
     55       swap(son[x,1],son[x,2]);
     56       rev[x]:=false;
     57     end;
     58     if (mul[x]<>1) or (add[x]<>0) then
     59     begin
     60       if son[x,1]<>0 then calc(son[x,1],mul[x],add[x]);
     61       if son[x,2]<>0 then calc(son[x,2],mul[x],add[x]);
     62       mul[x]:=1;
     63       add[x]:=0;
     64     end;
     65   end;
     66 
     67 procedure rotate(x,w:longint);
     68   var y:longint;
     69   begin
     70     y:=fa[x];
     71     if not root(y) then
     72     begin
     73       if son[fa[y],1]=y then son[fa[y],1]:=x
     74       else son[fa[y],2]:=x;
     75     end;
     76     fa[x]:=fa[y];
     77     son[y,3-w]:=son[x,w];
     78     if son[x,w]<>0 then fa[son[x,w]]:=y;
     79     son[x,w]:=y;
     80     fa[y]:=x;
     81     update(y);
     82   end;
     83 
     84 procedure splay(x:longint);
     85   var y,t,i:longint;
     86       ff:boolean;
     87   begin
     88     t:=0;
     89     i:=x;
     90     while not root(i) do
     91     begin
     92       inc(t);
     93       q[t]:=i;
     94       i:=fa[i];
     95     end;
     96     inc(t);
     97     q[t]:=i;
     98     for i:=t downto 1 do
     99       push(q[i]);
    100     ff:=true;
    101     if t=1 then exit; 
    102     while ff do
    103     begin
    104       y:=fa[x];
    105       if y=q[t] then
    106       begin
    107         if son[y,1]=x then rotate(x,2)
    108         else rotate(x,1);
    109         ff:=false;
    110       end
    111       else begin
    112         if fa[y]=q[t] then ff:=false;
    113         if son[fa[y],1]=y then
    114         begin
    115           if son[y,1]=x then rotate(y,2)
    116           else rotate(x,1);
    117           rotate(x,2);
    118         end
    119         else begin
    120           if son[y,1]=x then rotate(x,2)
    121           else rotate(y,1);
    122           rotate(x,1);
    123         end;
    124       end;
    125     end;
    126     update(x);
    127   end;
    128 
    129 procedure access(x:longint);
    130   var y:longint;
    131   begin
    132     y:=0;
    133     repeat
    134       splay(x);
    135       son[x,2]:=y;
    136       update(x);  //这里要记得维护
    137       y:=x;
    138       x:=fa[x];
    139     until x=0;
    140   end;
    141 
    142 procedure makeroot(x:longint);
    143   begin
    144     access(x);  //执行access之后,x和当前树的根之间的路径构成Auxiliary tree
    145     splay(x);   //将x旋到Auxiliary tree的根,这时候x没有右孩子,左子树的点都是x的祖辈
    146     rev[x]:=not rev[x];  //执行翻转操作,这时候x是Auxiliary tree上最小的点,也就变成了原树的根
    147   end;
    148 
    149 procedure link(x,y:longint);
    150   begin
    151     makeroot(x);
    152     fa[x]:=y;
    153   end;
    154 
    155 procedure cut(x,y:longint); 
    156   begin
    157     makeroot(x);
    158     access(y);
    159     splay(y);
    160     son[y,1]:=0;
    161     fa[x]:=0;
    162   end;
    163 
    164 procedure path(x,y:longint); //构成x到y的路径
    165   begin
    166     makeroot(x);
    167     access(y); //x到y路径上的点就在一棵Auxiliary tree中
    168     splay(y);  
    169   end;
    170 
    171 begin
    172   readln(n,m);
    173   for i:=1 to n do
    174   begin
    175     a[i]:=1;
    176     size[i]:=1;
    177     sum[i]:=1;
    178     mul[i]:=1;
    179   end;
    180   for i:=1 to n-1 do
    181   begin
    182     readln(x,y);
    183     link(x,y);
    184   end;
    185   for i:=1 to m do
    186   begin
    187     read(ch);
    188     if ch='+' then
    189     begin
    190       readln(x,y,z);
    191       z:=z mod mo;
    192       path(x,y);
    193       calc(y,1,z);
    194     end
    195     else if ch='-' then
    196     begin
    197       readln(x0,y0,x,y);
    198       cut(x0,y0);
    199       link(x,y);
    200     end
    201     else if ch='*' then
    202     begin
    203       readln(x,y,z);
    204       z:=z mod mo;
    205       path(x,y);
    206       calc(y,z,0);
    207     end
    208     else begin
    209       readln(x,y);
    210       path(x,y);
    211       writeln(sum[y]);
    212     end;
    213   end;
    214 end.
    View Code
  • 相关阅读:
    Dalvik虚拟机进程和线程的创建过程分析
    Dalvik虚拟机的运行过程分析
    Dalvik虚拟机JNI方法的注册过程分析
    Dalvik虚拟机简要介绍和学习计划
    Dalvik虚拟机的启动过程分析
    Android应用程序资源的查找过程分析
    Android应用程序资源管理器(Asset Manager)的创建过程分析
    Android应用程序资源的编译和打包过程分析
    Android视图SurfaceView的实现原理分析
    MySQL中CASE的使用
  • 原文地址:https://www.cnblogs.com/phile/p/4472992.html
Copyright © 2011-2022 走看看