luogu_P3203 [HNOI2010]弹飞绵羊

传送门:https://www.luogu.org/problem/P3203

不会LCT,这题分块直接水。

记录一下走几步到下一个块,到下一个块的那个位置。

然后就没了。

#include<cstdio>
#include<cmath>
#define R register
using namespace std;
int n,k[201000],m,sz;
int stp[200100],fl[200100],bel[200200],l[500],r[500];
inline int work(int x){
    int an=0;
    while(stp[x]){
        an+=stp[x];
        x=fl[x];
    }
    return an;
}
inline void change(int x,int y){
    k[x]=y;
    for(R int i=x;i>=l[bel[x]];i--){
        if(bel[i+k[i]]!=bel[i]){
            stp[i]=1;
            fl[i]=i+k[i];
        }
        else{
            stp[i]=stp[i+k[i]]+1;
            fl[i]=fl[i+k[i]];
        }
    }
}
int main (){
    scanf("%d",&n);
    sz=sqrt(n);
    for(R int i=1;i<=n;i++){
        scanf("%d",&k[i]);
        bel[i]=(i-1)/sz+1;
        if(!l[(i-1)/sz+1]) l[(i-1)/sz+1]=i;
        r[(i-1)/sz+1]=i;
    }
    for(R int i=n;i;i--){
        if(bel[i+k[i]]!=bel[i]){
            stp[i]=1;
            fl[i]=i+k[i];
        }
        else{
            stp[i]=stp[i+k[i]]+1;
            fl[i]=fl[i+k[i]];
        }
    }
    scanf("%d",&m);
    for(R int op,x,y,i=1;i<=m;i++){
        scanf("%d",&op);
        if(op==1){
            scanf("%d",&x);
            x++;
            printf("%d\n",work(x));
        }
        else{
            scanf("%d%d",&x,&y);
            x++;
            change(x,y);
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/coclhy/p/11732405.html