[HNOI2010] 弹飞绵羊 (分块)

[HNOI2010] 弹飞绵羊

题目描述

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

输入输出格式

输入格式:

第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1。

接下来一行有n个正整数,依次为那n个装置的初始弹力系数。

第三行有一个正整数m,

接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。

输出格式:

对于每个i=1的情况,你都要输出一个需要的步数,占一行。

输入输出样例

输入样例#1:

4
1 2 1 1
3
1 1
2 1 1
1 1

输出样例#1:

2
3

说明

对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

Solution

分块...

对于块中每个点,我们统计它什么时候会弹出块,以及弹出块后会弹到哪里

对于修改(将v[x]修改为y),我们只需要暴力修改本块内x之前的信息,因为后面的我们不会影响,最坏时间复杂度(O(sqrt n))

对于查询操作,我们每次都会跳一个块,最坏跳(sqrt n)个,所以最坏时间复杂度也是(O(sqrt n))

然后就没了...

Code

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define rg register
#define lol long long
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)
#define in(i) (i=read())
using namespace std;
const int N=2e5+10;
int read() {
    int ans=0,f=1; char i=getchar();
    while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
    while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();
    return ans*f;
}
int n,m,blo;
int v[N],pos[N],l[530],r[530],nex[N],sum[N];
void change(int x,int y) {
    v[x]=y; int AQ=pos[x];
    for(int i=x;i>=l[AQ];i--)
        if(i+v[i]>r[AQ]) sum[i]=1,nex[i]=i+v[i];
        else sum[i]=sum[i+v[i]]+1,nex[i]=nex[i+v[i]];
}

int query(int x,int ans=0) {
    while(x<=n) {
        ans+=sum[x];
        x=nex[x];
    }return ans;
}
int main() {
    in(n); blo=sqrt(n);
    for(int i=1;i<=n;i++) in(v[i]),pos[i]=(i-1)/blo+1;
    for(int i=1;i<=pos[n];i++) {
        l[i]=r[i-1]+1,r[i]=Min(i*blo,n);
        for(int j=r[i];j>=l[i];j--)
            if(j+v[j]>r[i]) sum[j]=1,nex[j]=j+v[j];
            else sum[j]=sum[j+v[j]]+1,nex[j]=nex[j+v[j]];
    }
    in(m);
    while(m--) {
        int a,b,c; in(a),in(b),b++;
        if(a==1) printf("%d
",query(b));
        else in(c),change(b,c);
    }
}
原文地址:https://www.cnblogs.com/real-l/p/9768940.html