• bzoj 2002 LCT


    LCT最基础的题,就用到了一个ACCESS操作

    首先我们将这个绵羊弹飞的情况看成一颗树,那么假设X点被弹飞到

    Y点,那么Y为X的父亲节点,弹飞的话父亲节点为n+1(虚设)

    那么每个询问就是询问X点到根节点n+1的路径长度(节点数)

    每个修改操作就是将以X为根节点的子树和X的父亲断开,连接到Y上

    这样简单的维护森林连通性的问题,动态树中的LCT解决就行了

    /**************************************************************
        Problem: 2002
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:2372 ms
        Memory:4328 kb
    ****************************************************************/
     
    //By BLADEVIL
    var
        n, m                :longint;
        father, size        :array[-1..200010] of longint;
        son                 :array[-1..200010,0..2] of longint;
        root                :array[-1..200010] of boolean;
     
    procedure update(x:longint);
    begin
        size[x]:=size[son[x,0]]+size[son[x,1]]+1;
    end;
         
    procedure left_rotate(x:longint);
    var
        y                   :longint;
    begin
        y:=son[x,1];
        son[x,1]:=son[y,0];
        father[son[x,1]]:=x;
        son[y,0]:=x;
        if x=son[father[x],0] then
            son[father[x],0]:=y else
        if x=son[father[x],1] then
            son[father[x],1]:=y;
        father[y]:=father[x];
        father[x]:=y;
        root[y]:=root[x] xor root[y];
        root[x]:=root[x] xor root[y];
        update(x); update(y);
    end;
     
    procedure right_rotate(x:longint);
    var
        y                   :longint;
    begin
        y:=son[x,0];
        son[x,0]:=son[y,1];
        father[son[x,0]]:=x;
        son[y,1]:=x;
        if x=son[father[x],0] then
            son[father[x],0]:=y else
        if x=son[father[x],1] then
            son[father[x],1]:=y;
        father[y]:=father[x];
        father[x]:=y;
        root[y]:=root[y] xor root[x];
        root[x]:=root[y] xor root[x];
        update(x); update(y);
    end;
         
    procedure splay(x:longint);
    begin
        while not root[x] do
            if x=son[father[x],1] then
                left_rotate(father[x]) else
                right_rotate(father[x]);
    end;
         
    procedure access(x:longint);
    var
        y                   :longint;
    begin
        splay(x);
        while father[x]<>0 do
        begin
            y:=father[x];
            splay(y);
            root[son[y,1]]:=true;
            root[x]:=false;
            son[y,1]:=x;
            update(y);
            splay(x);
        end;
    end;
         
    procedure init;
    var
        i                   :longint;
    begin
        read(n);
        for i:=1 to n do
        begin
            read(father[i]);
            father[i]:=father[i]+i;
            if father[i]>n then father[i]:=n+1;
        end;
        read(m);
    end;
     
    procedure main;
    var
        i                   :longint;
        x, y, z             :longint;
    begin
        for i:=1 to n+1 do size[i]:=1;
        fillchar(root,sizeof(root),true);
        for i:=1 to m do
        begin
            read(x);
            if x=1 then
            begin
                read(y); inc(y);
                access(y);
                writeln(size[son[y,0]]);
            end else
            begin
                read(y,z); inc(y);
                splay(y);
                father[son[y,0]]:=father[y];
                root[son[y,0]]:=true;
                son[y,0]:=0; 
                size[y]:=size[son[y,1]]+1;
                father[y]:=y+z;
                if father[y]>n then father[y]:=n+1;
            end;
        end;
    end;
         
    begin
        init;
        main;
    end.
  • 相关阅读:
    转载:Python十分钟入门
    Think Python: How to Think Like a Computer Scientist
    LeetCode(34):搜索范围
    LeetCode(33):搜索旋转排序数组
    LeetCode(32):最长有效括号
    LeetCode(31): 下一个排列
    LeetCode(30):与所有单词相关联的字串
    LeetCode(29): 两数相除
    LeetCode(28): 实现strStr()
    LeetCode(27): 移除元素
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3508369.html
Copyright © 2020-2023  润新知