• bzoj2002 弹飞绵羊


    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的情况,你都要输出一个需要的步数,占一行。

    用块状树维护由跳跃一次后位置到跳跃前位置连边构成的有根树。

    每操作O(n0.5)次重构整棵树

    均摊时间复杂度O(n1.5)

    #include<cstdio>
    #include<cmath>
    int n,m,rt;
    int cs,cb,tt=0,cb2;
    int fa[200005],fw[200005],v[200005],dep[200005],top[200005];
    int enx[800005],epv[800005],ew[800005],ep;
    inline int min(int a,int b){
        return a<b?a:b;
    }
    void addedge(int a,int b){
        fa[b]=a;
        ew[ep]=b;
        enx[epv[ep]=epv[a]]=ep;
        enx[ep]=a;
        fw[b]=epv[a]=ep++;
    }
    void deledge(int a){
        int x=fw[a],pv=epv[x];
        epv[enx[pv]=enx[x]]=pv;
    }
    int getdep(int x){
        int ans=-1;
        while(x){
            ans+=dep[x];
            x=fa[top[x]];
        }
        return ans;
    }
    void build(int w){
        ++cs;
        if(cs<=cb)top[w]=top[fa[w]],dep[w]=dep[fa[w]]+1;
        else cs=0,top[w]=w,dep[w]=1;
        for(int i=enx[w],u=ew[i];u=ew[i];i=enx[i])build(u);
    }
    int tp,tpn,dp;
    void dfs(int w){
        if(top[w]!=tp)return;
        top[w]=tpn;
        dep[w]=dp;
        ++dp;
        for(int i=enx[w],u=ew[i];u=ew[i];i=enx[i])dfs(u);
        --dp;
    }
    int main(){
        scanf("%d",&n);
        cb=sqrt(n);
        cb2=cb*3;
        rt=n+1;
        for(int i=1;i<=n;i++)scanf("%d",v+i);
        for(int i=1;i<=rt;i++)enx[i]=epv[i]=i;ep=rt+1;
        for(int i=1;i<=n;i++)addedge(min(i+v[i],rt),i);
        scanf("%d",&m);
        cs=cb,build(rt);
        while(m--){
            int op,a,b;
            scanf("%d",&op);
            if(op==2){
                scanf("%d%d",&a,&b);++a;
                v[a]=b;
                deledge(a);
                addedge(min(a+v[a],rt),a);
                tp=top[a],tpn=a,dp=1,dfs(a);
                if(++tt>cb2)cs=cb,build(rt),tt=0;
            }else{
                int vans;
                scanf("%d",&a);++a;
                printf("%d
    ",vans=getdep(a));
            }
        }
        return 0;
    }
  • 相关阅读:
    LAMP应用 wdlinux 配置文件
    Linux mysql忘记root密码
    vim 编辑器 常用的设置
    Virtual PC(VPC)虚拟机安装CentOS 6.0网络配置
    缓存系统memcache的安装,配置和使用
    CentOS 去掉Last login提示/系统欢迎信息
    configure: error: GD build test failed. Please check the config.log for details.
    Centos 6.0 yum 更新源
    MySQL is running but PID file is not found
    Visual Studio快速开发以及Visual Studio 2010新功能介绍
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5289664.html
Copyright © 2020-2023  润新知