BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)

http://www.lydsy.com/JudgeOnline/problem.php?id=2002

题意

 

思路

不会LCT,就只好用分块了。

将这n个数分成根号n块,对于每一块中的每一个数,处理出它跳出它所在块的下一个位置和所需跳数。

这样如果要修改x的话,我们只需要修改一个x所在的块即可。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = 200000+5;

int n, m;
int a[maxn],pos[maxn],jump[maxn];

int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=0;i<n;i++)  scanf("%d",&a[i]);
    int block = sqrt(n+0.5);
    for(int i=n-1;i>=0;i--)
    {
        int tmp = i+a[i];
        if(tmp>=n)  {pos[i]=-1;jump[i]=1;}
        else if(tmp>=(i/block+1)*block)  {pos[i]=tmp;jump[i]=1;}
        else {pos[i]=pos[tmp];jump[i]=jump[tmp]+1;}
    }
    scanf("%d",&m);
    while(m--)
    {
        int x,y;
        int op; scanf("%d",&op);
        if(op==1)
        {
            int ans = 0;
            scanf("%d",&x);
            for(int i=x;i!=-1;i=pos[i]) ans+=jump[i];
            printf("%d\n",ans);
       }
       else
       {
           scanf("%d%d",&x,&y);
           a[x]=y;
           for(int i=x;i>=x/block*block;i--)
           {
               int tmp = i+a[i];
               if(tmp>=n)  {pos[i]=-1;jump[i]=1;}
               else if(tmp>=(i/block+1)*block)  {pos[i]=tmp;jump[i]=1;}
               else {pos[i]=pos[tmp];jump[i]=jump[tmp]+1;}
           }
       }
    }
    return 0;
}

  

 

posted @ 2017-10-19 21:48  Kayden_Cheung  阅读(99)  评论(0编辑  收藏
//目录