zoukankan      html  css  js  c++  java
  • bzoj2002 弹飞绵羊 LCT

    2002: [Hnoi2010]Bounce 弹飞绵羊

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 6706  Solved: 3522
    [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
    显然这里不能换根,然后直接维护下size就可以了。
    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    int n,m;
    int op,x,k;
    int pre[maxn],ch[maxn][2];
    int sz[maxn];
    
    bool isroot(int x)
    {
        return ch[pre[x]][0]!=x&&ch[pre[x]][1]!=x;
    }
    
    void up(int x)
    {
        sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
    }
    
    void rot(int x,int kind)
    {
        int y=pre[x];
        ch[y][kind^1]=ch[x][kind];
        pre[ch[x][kind]]=y;
        if(!isroot(y)) ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];
        ch[x][kind]=y;
        pre[y]=x;
        up(y);
    }
    
    void splay(int x)
    {
        while(!isroot(x)){
            if(isroot(pre[x])) rot(x,ch[pre[x]][0]==x);
            else{
                int y=pre[x],z=pre[y];
                int kind=ch[y][0]==x,one=0;
                if(ch[y][0]==x&&ch[z][0]==y) one=1;
                if(ch[y][1]==x&&ch[z][1]==y) one=1;;
                if(one) rot(y,kind),rot(x,kind);
                else rot(x,kind),rot(x,kind^1);
            }
        }
        up(x);
    }
    
    int access(int x)
    {
        int t=0;
        while(x){
            splay(x);
            ch[x][1]=t;
            t=x;x=pre[x];
            up(t);
        }
        return t;
    }
    
    int get(int x)
    {
        access(x);
        splay(x);
        return sz[ch[x][0]];
    }
    
    void cut(int x)
    {
        access(x);
        splay(x);
        ch[x][0]=pre[ch[x][0]]=0;
        up(x);
    }
    
    void link(int x,int y)
    {
        access(x);
        splay(x);
        pre[x]=y;
        splay(x);
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        while(cin>>n){
            REP(i,0,n) pre[i]=0,MS0(ch[i]),sz[i]=i?1:0;
            REP(i,1,n){
                scanf("%d",&k);
                if(i+k<=n) link(i,i+k);
            }
            cin>>m;
            REP(i,1,m){
                scanf("%d%d",&op,&x);x++;
                if(op==1) printf("%d
    ",get(x)+1);
                else{
                    scanf("%d",&k);
                    cut(x);
                    if(x+k<=n) link(x,x+k);
                }
            }
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    nodeJS实现完整文件夹结构压缩
    chrome浏览器插件开发
    让用户端JS触发F11全屏
    inline-block和float的共性和区别
    安家落户
    ActiveMQ简单实现之一对一生产和消费
    Centos下 修改mysql密码
    虚拟机centos7 安装was和ihs
    webservice简单实现
    Centos7安装mysql
  • 原文地址:https://www.cnblogs.com/--560/p/5231962.html
Copyright © 2011-2022 走看看