zoukankan      html  css  js  c++  java
  • BZOJ-2002 弹飞绵羊 Link-Cut-Tree (分块)

    2002: [Hnoi2010]Bounce 弹飞绵羊
    Time Limit: 10 Sec Memory Limit: 259 MB
    Submit: 6801 Solved: 3573
    [Submit][Status][Discuss]

    Description
    某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

    Input
    第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

    Output
    对于每个i=1的情况,你都要输出一个需要的步数,占一行。

    Sample Input
    4
    1 2 1 1
    3
    1 1
    2 1 1
    1 1

    Sample Output
    2
    3

    HINT

    Source

    套LCT即可,需要维护子树的size,弹的时候处理好即可
    分块也可做,等我搞定分块,再来搞搞
    

    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define N 200100
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int f[N],son[N][2],tmp[N];bool rev[N];
    int next[N],size[N];
    
    bool isroot(int x)
    {
        return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;
    }
    
    void rev1(int x)
    {
        if(!x) return;
        swap(son[x][0],son[x][1]);
        rev[x]^=1;
    }
    
    void pb(int x)
    {
        if(rev[x])
            rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;
    }
    
    void updata(int x)
    {
        size[x]=size[son[x][0]]+size[son[x][1]]+1;
    }
    
    void rotate(int x)
    {
        int y=f[x],w=son[y][1]==x;
        son[y][w]=son[x][w^1];
        if(son[x][w^1]) f[son[x][w^1]]=y;
        if(f[y])
            {
                int z=f[y];
                if(son[z][0]==y)son[z][0]=x;
                    else if(son[z][1]==y)son[z][1]=x;
            }
        f[x]=f[y];f[y]=x;
        son[x][w^1]=y;
        updata(x);updata(y);
    }
    
    void splay(int x)
    {
        int s=1,i=x,y;tmp[1]=i;
        while(!isroot(i)) tmp[++s]=i=f[i];
        while(s) pb(tmp[s--]);
        while(!isroot(x))
            {
                y=f[x];
                if(!isroot(y))
                    {
                        if((son[f[y]][0]==y)^(son[y][0]==x))
                        rotate(x);  else  rotate(y);
                    }
                rotate(x);
            }
    }
    
    void access(int x)
    {
        for(int y=0;x;y=x,x=f[x])
            splay(x),son[x][1]=y;
    }
    
    void makeroot(int x)
    {
        access(x);splay(x);rev1(x);
    }
    
    void link(int x,int y)
    {
        makeroot(x);
        f[x]=y;
        access(x);
    }
    
    void cutf(int x)
    {
        access(x);splay(x);
        f[son[x][0]]=0;son[x][0]=0;
    }
    void cut(int x,int y)
    {
        makeroot(x);cutf(y);
    }
    
    int n,m;
    int main()
    {
        n=read();
        for (int i=1; i<=n; i++)
            {
                int x=read();
                size[x]=1;
                f[i]=x+i;if (f[i]>n+1) f[i]=n+1;
                next[i]=f[i];
            }
            size[n+1]=1;
        m=read();
        for (int i=1; i<=m; i++)
            {
                int com=read();
                if (com==1)
                    {
                        int x=read();
                        makeroot(n+1);
                        access(x+1);splay(x+1);
                        printf("%d
    ",size[son[x+1][0]]);
                    }
                else
                    {
                        int x=read(),y=read();
                        int temp=min(n+1,x+y+1);
                        cut(x+1,next[x+1]);link(x+1,temp);
                        next[x+1]=temp;
                    }
            }
        return 0;
    }
  • 相关阅读:
    转载:SQL Server错误 2812 :未能找到存储过程 ***的解决方法
    转载:mysql5.7设置不区分大小写
    无法对数据库'XXX' 执行删除,因为它正用于复制"
    Win7 64位 部分软件和文档字体显示乱码
    转载:创建对于用户sa失败,sa无法映射到数据库
    sqlserver 用户角色权限
    转发:Nginx可视化配置工具—NginxWebUI
    docker-compose安装
    导入导出windows 防火墙规则
    python 打包pyinstaller 问题记录
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346168.html
Copyright © 2011-2022 走看看