Bounce 弹飞绵羊 HYSBZ

//预处理出以这个点为起点并跳出这个块的次数和位置
//更新一个点的弹力系数可以只更新这个点以及这个块内之前的点 
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<cmath>
#include<iostream>
using namespace std;
const int N=2e5+10; 
struct node
{
    //ahead为从该点跳的距离 
    int ahead;
    //step为跳到下一个块的所需步数
    int step;  
    //Next为跳到的下一个块  跳出Next为0
    int Next;
    //pos为跳到下一个块的位置
    int pos;
}p[N];
int temp;
int block[N];
int main()
{
    int n,m,op;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
        scanf("%d",&p[i].ahead);
    temp=sqrt(n);
    //分块
    for(int i=0; i<n; i++)
        block[i]=i/temp+1;
    for(int i=n-1; i>=0; i--)
    {
        //如果在同一个块内 
        if(block[i+p[i].ahead]!=block[i])
        {
            p[i].Next=block[i+p[i].ahead];
            p[i].pos=i+p[i].ahead;
            p[i].step=1;
        }
        else
        {
            p[i].Next=p[i+p[i].ahead].Next;
            p[i].pos=p[i+p[i].ahead].pos;
            p[i].step=p[i+p[i].ahead].step+1;
        }
    }
    scanf("%d",&m);
    int x,y;
    for(int cas=1; cas<=m; ++cas)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d",&x);
            int ans=0;
            //一个块一个块的跳
            while(p[x].Next!=0)
            {
                ans+=p[x].step;
                x=p[x].pos;
            }
            ans+=p[x].step;
            printf("%d
",ans);
        }
        else if(op==2)//更新
        {
            scanf("%d%d",&x,&y);
            p[x].ahead=y;
            //更新的话,只更新在同一块内的 
            int l=(block[x]-1)*temp;
            for(int i=x; i>=l; i--)
            {
                if(block[i+p[i].ahead]!=block[i])
                {
                    p[i].Next=block[i+p[i].ahead];
                    p[i].pos=i+p[i].ahead;
                    p[i].step=1;
                }
                else
                {
                    p[i].Next=p[i+p[i].ahead].Next;
                    p[i].pos=p[i+p[i].ahead].pos;
                    p[i].step=p[i+p[i].ahead].step+1;
                }
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12349013.html