zoukankan      html  css  js  c++  java
  • luoguP3203 [HNOI2010]BOUNCE 弹飞绵羊

    P3203 [HNOI2010]BOUNCE 弹飞绵羊

    题目描述

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

    输入输出格式

    输入格式:

    第一行包含一个整数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

    输出格式:

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

    输入输出样例

    输入样例#1:
    4
    1 2 1 1
    3
    1 1
    2 1 1
    1 1
    输出样例#1:
    2
    3

     思路:

      分块什么的

    坑点:

      1.注意是从0号元素开始!!!

      2.在luogu上最好不要用next数组...

    代码:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    const int M = 200000;
    const int N = 1000;
    int n,m;
    int k[M],steps[M],nxt[M];
    ///step数组存的是需要多少步跳出当前块
    ///next数组存的是跳到(下一块)的下一个点 
    int len,ks,kuai[M],l[N],r[N];///分块 
    
    void Builds()
    {
        ///块的长度
        len=sqrt(n);
        ///块的个数 
        ks=len;
        if(n%ks) ks++;
        ///分块 
        for(int i=0;i<n;i++)
            kuai[i]=(i-1)/len;
        /*
            因为块数是从0号开始计数的,
            当i==(√n)时如果不进行-1,
            会被分到第一块,
            但事实上它是第0块的,
            所以进行-1 
        */ 
        for(int i=1;i<=ks;i++)
        {
            l[i]=(i-1)*len;
            ///r[i]=i*len-1中-1的原因是:
            ///因为数组是从0号开始储存的 
            r[i]=i*len-1;
        }
        ///将最后一块的右端手动设置为n的长度 
        r[ks]=n;
        for(int i=n-1;i>=0;i--)
        {
            int now=i+k[i];
            ///如果下一步跳到的地方已经跳出最远的距离n的话 
            if(now>=n)
                ///更新步数:跳一步就跳出去 
                steps[i]=1,
                ///这里重要!需要手动将next数组设置一个不可能出现的数值 
                    nxt[i]=-1;
            else 
            ///假如在同一块中 
                if(kuai[i]==kuai[now])
                ///更新步数,i的步数由now的步数多跳一步来到当前(点)位置 
                    steps[i]=steps[now]+1,
                    ///更新接下来跳到的点是... 
                        nxt[i]=nxt[now];
            else
            ///不在一块中 
                steps[i]=1,
                ///跳到now这个点 
                    nxt[i]=now; 
        }
    }
    
    int ask(int pre)
    {
        int ans=0;
        while(pre!=-1)
        {
            ans+=steps[pre];
            pre=nxt[pre];
        }
        return ans;
     } 
    
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&k[i]);
        ///开始分块 
        Builds();
        scanf("%d",&m);
        for(int i=0,c;i<m;i++)
        {
            scanf("%d",&c);
            if(c==1)
            {
                int pre;
                scanf("%d",&pre);
                printf("%d
    ",ask(pre)); 
            }
            else 
            {
                int pre,ki;
                scanf("%d%d",&pre,&ki);
                ///更新k值 
                k[pre]=ki;
                ///因为更改k之后只会影响到当前块,并且只会影响他前面的 
                for(int j=pre;j>=l[kuai[pre]];j--)
                {
                    int now=j+k[j];
                    if(now>=n)
                        steps[j]=1,
                            nxt[j]=-1;
                    else 
                        if(kuai[j]==kuai[now])
                            steps[j]=steps[now]+1,
                                nxt[j]=nxt[now];
                    else
                        steps[j]=1, 
                            nxt[j]=now; 
                }
            }
        }
        return 0;
    }
    View Code

    如果运气好也是错,那我倒愿意错上加错!

    ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀

  • 相关阅读:
    【hdu4285】 circuits
    java代码获取ip地址
    java覆写hashcode方法
    java覆写equals方法
    Linux下Apache服务器并发优化
    异常:cvc-complex-type.2.4.a: Invalid content was found starting with element
    SpringMVC请求访问不到静态文件解决方式
    mina教程
    分布式session
    jsp自定义标签
  • 原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/7125274.html
Copyright © 2011-2022 走看看