zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    hdu 4710 Balls Rearrangement()
    hdu 4707 Pet(DFS水过)
    hdu 4706 Children's Day(模拟)
    hdu 4712 Hamming Distance(随机函数暴力)
    csu 1305 Substring (后缀数组)
    csu 1306 Manor(优先队列)
    csu 1312 榜单(模拟题)
    csu 1303 Decimal (数论题)
    网络爬虫
    Python处理微信利器——itchat
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3508369.html
Copyright © 2011-2022 走看看