zoukankan      html  css  js  c++  java
  • [bzoj2002][Hnoi2010]Bounce 弹飞绵羊

    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

    题解

    分块经典题...但是做法不好想啊...

    想了好久没什么头绪去翻了翻黄学长的博客,上面说处理出每一个点跳出块需要的次数和跳出块后到哪个点,瞬间就懂了...

    细节的话,就是在修改的时候记得整块都要一起修改,因为前面的点可能因为这个点变了而结果也变了

    还有查询和修改的时候下标是从0开始的话如果你习惯从1开始使用下标记得+1,我写的时候忘记了...

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #define ll long long
    #define N 200010
    inline void read(int &x){
        x=0;int f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=f;
    }
    using namespace std;
    int n,a[N],m;
    int block,num,to[N],d[N],l[N],r[N],belong[N];
    void build(){
        block=sqrt(n),num=n/block;
        if(n%block)num++;
        for(int i=1;i<=num;i++){
            l[i]=(i-1)*(block)+1;
            r[i]=block*i;
        } 
        r[num]=n;
        for(int i=1;i<=n;i++){
            belong[i]=(i-1)/block+1;
        }
        for(int i=n;i;i--){
            if(belong[i+a[i]]!=belong[i]){
                d[i]=1;
                to[i]=i+a[i];
            }else {
                d[i]=d[i+a[i]]+1;
                to[i]=to[i+a[i]];
            }
        }
    }
    void upd(int x,int c){
        a[x]=c;
        for(int i=r[belong[x]];i>=l[belong[x]];i--){
            if(belong[i+a[i]]!=belong[i]){
                to[i]=i+a[i];
                d[i]=1;
            }else {
                d[i]=d[i+a[i]]+1;
                to[i]=to[i+a[i]];
            }
        }
    }
    int query(int x){
        int ans=0;
        while(x<=n){
            ans+=d[x];
            x=to[x];
        }
        return ans;
    }
    int main(){
        read(n);
        for(int i=1;i<=n;i++)read(a[i]);
        build();
        read(m);
        while(m--){
            int x,y;
            read(x);read(y);
            if(x==1)printf("%d
    ",query(y+1));
            else {
                int k;read(k);
                upd(y+1,k);
            }
        }
    }
  • 相关阅读:
    git生成SSH秘钥
    ifconfig
    接口自动化测试平台:简介
    Gitd的使用
    jenkins自动化部署和Tomcat中间件容器
    Struts2——用来开发 MVC 应用程序的框架,可用于创建企业级Java web应用程序
    Hibernate——Java 领域的持久化ORM框架
    jQuery——JavaScript库
    JavaScript HTML DOM——文档对象模型
    JVM 完整深入解析
  • 原文地址:https://www.cnblogs.com/henry-1202/p/9507998.html
Copyright © 2011-2022 走看看