• 【BZOJ2002】弹飞绵羊(LCT)


    题意:给定一棵树,要求维护以下操作:

    1.删除连接(x,y)的边

    2.将(x,y)之间连边

    3.询问某点子树大小

    对于100%的数据n<=200000,m<=100000

    思路:第一道有加边删边的LCT

    讲一下自己对LCT各个操作的理解

    Access:最基本的操作,将一个点到LCT的根的点全部修改为重(实)边

    可以理解为“全选操作”,配合Splay操作可以取出某段区间的信息

    Splay:将X旋转到它所在链的顶部,这样就相当于将这条链中的信息集中到了X这个点上

    LCT的splay要用栈pushdown维护的原因是普通splay中splay操作前这些信息已经在Findkth的时候下传

    而LCT没有,需要手动下传

    Findroot:找到LCT的根,先Access+splay,因为LCT是按照深度维护的,所以一直往左走,找到深度最小的就是根

    Makeroot:将X设置为LCT的根,Access+splay,因为上下翻转了所以要打翻转标记

    Link:链接两个不在同一条链上的点,Makeroot(x),fa[x]=y

    split:取出(x,y)这段区间的信息,Makeroot(x),Access(y),splay(y),信息在y点上

    此题输出左儿子的子树大小即可

      1 var t:array[0..500000,0..1]of longint;
      2     next,fa,rev,size,q:array[0..500000]of longint;
      3     n,m,i,x,y,tmp,top:longint;
      4 
      5 function isroot(x:longint):boolean;
      6 begin
      7  if (t[fa[x],0]<>x)and(t[fa[x],1]<>x) then exit(true);
      8  exit(false);
      9 end;
     10 
     11 procedure swap(var x,y:longint);
     12 var t:longint;
     13 begin
     14  t:=x; x:=y; y:=t;
     15 end;
     16 
     17 procedure pushup(x:longint);
     18 var l,r:longint;
     19 begin
     20  l:=t[x,0]; r:=t[x,1];
     21  size[x]:=size[l]+size[r]+1;
     22 end;
     23 
     24 procedure pushdown(x:longint);
     25 var l,r:longint;
     26 begin
     27  l:=t[x,0]; r:=t[x,1];
     28  if rev[x]>0 then
     29  begin
     30   rev[x]:=rev[x] xor 1; rev[l]:=rev[l] xor 1; rev[r]:=rev[r] xor 1;
     31   swap(t[x,0],t[x,1]);
     32  end;
     33 end;
     34 
     35 procedure rotate(x:longint);
     36 var y,z,l,r:longint;
     37 begin
     38  y:=fa[x]; z:=fa[y];
     39  if t[y,0]=x then l:=0
     40   else l:=1;
     41  r:=l xor 1;
     42  while not isroot(y) do
     43  begin
     44   if t[z,0]=y then t[z,0]:=x
     45    else t[z,1]:=x;
     46  end;
     47  fa[x]:=z; fa[y]:=x; fa[t[x,r]]:=y;
     48  t[y,l]:=t[x,r]; t[x,r]:=y;
     49  pushup(y);
     50  pushup(x);
     51 end;
     52 
     53 procedure splay(x:longint);
     54 var y,z,k:longint;
     55 begin
     56  inc(top); q[top]:=x;
     57  k:=x;
     58  while not isroot(k) do
     59  begin
     60   inc(top); q[top]:=fa[k];
     61   k:=fa[k];
     62  end;
     63  while top>0 do
     64  begin
     65   pushdown(q[top]);
     66   dec(top);
     67  end;
     68 
     69  while not isroot(x) do
     70  begin
     71   y:=fa[x]; z:=fa[y];
     72   if not isroot(y) then
     73   begin
     74    if (t[y,0]=x)xor(t[z,0]=y) then rotate(x)
     75     else rotate(y);
     76   end;
     77   rotate(x);
     78  end;
     79 end;
     80 
     81 procedure access(x:longint);
     82 var last:longint;
     83 begin
     84  last:=0;
     85  while x>0 do
     86  begin
     87   splay(x); t[x,1]:=last; //pushup(x);
     88   last:=x; x:=fa[x];
     89  end;
     90 end;
     91 
     92 procedure makeroot(x:longint);
     93 begin
     94  access(x); splay(x); rev[x]:=rev[x] xor 1;
     95 end;
     96 
     97 procedure link(x,y:longint);
     98 begin
     99  makeroot(x); fa[x]:=y;
    100 end;
    101 
    102 procedure split(x,y:longint);
    103 begin
    104  makeroot(x); access(y); splay(y);
    105 end;
    106 
    107 procedure cut(x,y:longint);
    108 begin
    109  makeroot(x); access(y); splay(y); t[y,0]:=0; fa[x]:=0;
    110 end;
    111 
    112 function min(x,y:longint):longint;
    113 begin
    114  if x<y then exit(x);
    115  exit(y);
    116 end;
    117 
    118 begin
    119  assign(input,'bzoj2002.in'); reset(input);
    120  assign(output,'bzoj2002.out'); rewrite(output);
    121  readln(n);
    122  for i:=1 to n do
    123  begin
    124   read(x);
    125   fa[i]:=x+i; size[i]:=1;
    126   if fa[i]>n then fa[i]:=n+1;
    127   next[i]:=fa[i];
    128  end;
    129  size[n+1]:=1;
    130  readln(m);
    131  for i:=1 to m do
    132  begin
    133   read(x);
    134   case x of
    135    1:
    136    begin
    137     read(y); inc(y);
    138     split(n+1,y);
    139     writeln(size[t[y,0]]);
    140    end;
    141    2:
    142    begin
    143     read(x,y);
    144     inc(x); tmp:=min(x+y,n+1);
    145     cut(x,next[x]); link(x,tmp); next[x]:=tmp;
    146    end;
    147   end;
    148  end;
    149  close(input);
    150  close(output);
    151 end.
  • 相关阅读:
    Centos 下查看服务器CPU的信息
    网速的一些知识整理
    如何复制文件夹里面的全部内容? 在pc上
    DataGridView中CellClick的使用,选中一行触发的动作可以在这个方法里执行
    C# 文件的压缩与解压缩
    C#调用Exe 及 有参数的
    oracle提示 ORA12154: TNS: 无法解析指定的连接标识符 OCIEnvCreate 失败, 返回代码为1,但错误消息文本不可用
    C# 导出wps配置服务器 注意事项
    C# FTP 操作类
    组件服务问题
  • 原文地址:https://www.cnblogs.com/myx12345/p/6297148.html
Copyright © 2020-2023  润新知