【滚动训练】BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(分块)

题意

某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

题解

考虑分块维护区间信息,单次询问和修改可以做到 n n 的复杂度。
对于块内任意一个位置,维护两个两个信息,一个是经过多少次弹出本块,另一个是弹出本块外的落点。
对于询问操作,只需要遍历每块中的落点,直至弹出序列,单次询问需要 n n 次转移。
对于修改操作,除了修改对应位置的弹力系数,还需要修改块内的信息,因为对应位置的弹力系数变了,块内其他位置落到本位置的信息也变了(如经过多少次弹出本块),注意到块外的信息没有变,所以只需要 n n 次修改本块内的信息。

代码

#include
using namespace std;
const int nmax = 2e5+10;
const int INF = 0x3f3f3f3f;
const int mm = 1000;
int n,m;
int num,block,L[mm],R[mm],belong[nmax],rx[nmax],step[nmax],nxtpos[nmax];
void build(){
    block = 3*sqrt(n);
    num = n / block; if(n%block) num++;
    for(int i = 1;i<=num;++i){
        L[i] = (i-1) * block + 1;
        R[i] = i*block;
    }
    R[num] = n;
}
void init(){
    for(int i = num;i>=1;--i){
        for(int j = R[i];j>=L[i];--j){
            if(j + rx[j] > n) nxtpos[j] = n+1, step[j] = 1;
            else{
                int pos = j + rx[j];
                if(belong[pos] == belong[j]) nxtpos[j] = nxtpos[pos],step[j] = step[pos] + 1;
                else nxtpos[j] = pos, step[j] = 1;
            }
        }
    }
}
int main() {
    scanf("%d",&n);
    build();
    for(int i = 1;i<=n;++i){
        scanf("%d",&rx[i]);
        belong[i] = (i-1) / block + 1;
    }
    init();
    scanf("%d",&m);
    int op,a,b;
    for(int i = 1;i<=m;++i){
        scanf("%d %d",&op,&a); a++;
        if(op==1){
            int pos = a,cnt = 0;
            for(int j = a;j<=n;j=nxtpos[j]) cnt += step[j];
            printf("%d\n",cnt);
        }else{
            scanf("%d",&b);
            rx[a] = b;
            for(int j = a;j>=1;--j){
                if(belong[j] != belong[a]) break;
                else{
                    int pos = j+rx[j];
                    if(belong[pos] != belong[j]) step[j] = 1, nxtpos[j] = pos;
                    else step[j] = step[pos] + 1, nxtpos[j] = nxtpos[pos];
                }
            }
        }
    }
    return 0;
}

你可能感兴趣的:(BZOJ,数据结构---分块)