分块 bzoj2002

来源:互联网 发布:什么叫知世故而不世故 编辑:程序博客网 时间:2024/06/14 03:01

2002: [Hnoi2010]Bounce 弹飞绵羊

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 11512  Solved: 5833
[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

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int N = 200000 + 10, INF = 0x3f3f3f3f;int a[N];int pos[N],times[N];int main(){    int n,m,q;    while(scanf("%d",&n)!=EOF)    {        int i;        for(i=0; i<n; i++)            scanf("%d",&a[i]);        int block=(int)sqrt((double)(n+0.00001));        for(i=n-1; i>=0; i--)        {            int t=i+a[i];            if(t>=n)                pos[i]=-1,times[i]=1;            else if(t>=(i/block+1)*block)                pos[i]=t,times[i]=1;            else pos[i]=pos[t],times[i]=times[t]+1;        }        scanf("%d",&m);        while(m--)        {            int x,y,ans;            scanf("%d",&q);            if(q==1)            {                scanf("%d",&x);                ans=0;                for(i=x; i!=-1; i=pos[i])                {                    ans+=times[i];                }                printf("%d\n",ans);            }            else            {                scanf("%d%d",&x,&y);                a[x]=y;                for(i=x; i>=(x/block)*block; i--)                {                    int t=i+a[i];                    if(t>=n)                        pos[i]=-1,times[i]=1;                    else if(t>=(i/block+1)*block)                        pos[i]=t,times[i]=1;                    else pos[i]=pos[t],times[i]=times[t]+1;                }            }        }    }    return 0;}


原创粉丝点击