B:http://www.fjutacm.com/Contest.jsp?cid=719#P1
题
解
:
考
虑
到
可
能
会
有
1111....11
这
种
毒
瘤
数
据
,
用
分
块
进
行
维
护
。
题解:考虑到可能会有1111....11这种毒瘤数据,用分块进行维护。
题解:考虑到可能会有1111....11这种毒瘤数据,用分块进行维护。
先
对
每
一
个
点
进
行
分
块
,
维
护
每
一
块
的
右
边
界
r
,
用
于
判
断
每
个
点
经
过
跳
跃
后
是
否
跳
出
其
所
在
块
。
先对每一个点进行分块,维护每一块的右边界r,用于判断每个点经过跳跃后是否跳出其所在块。
先对每一个点进行分块,维护每一块的右边界r,用于判断每个点经过跳跃后是否跳出其所在块。
更
新
两
个
数
组
:
s
t
[
i
]
表
示
当
前
点
i
跳
出
它
所
在
的
块
需
要
的
步
数
,
i
d
[
i
]
表
示
i
跳
出
该
块
后
所
在
的
位
置
。
更新两个数组:st[i]表示当前点 i 跳出它所在的块需要的步数,id[i]表示i跳出该块后所在的位置。
更新两个数组:st[i]表示当前点i跳出它所在的块需要的步数,id[i]表示i跳出该块后所在的位置。
然
后
可
以
用
之
前
处
理
出
来
的
r
来
判
断
是
否
能
跳
出
该
块
。
然后可以用之前处理出来的r来判断是否能跳出该块。
然后可以用之前处理出来的r来判断是否能跳出该块。
对
于
每
次
更
新
,
那
么
也
只
需
要
在
块
内
进
行
更
新
。
对于每次更新,那么也只需要在块内进行更新。
对于每次更新,那么也只需要在块内进行更新。
复 杂 度 m ∗ n 复杂度m*\sqrt{n} 复杂度m∗n
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x) x&-x;
#define debugint(name,x) printf("%s: %d\n",name,x);
#define debugstring(name,x) printf("%s: %s\n",name,x);
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 2e5+5;
const int mod = 1e9+7;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int belong[maxn],block,num,r[maxn],st[maxn],id[maxn],a[maxn],n,m;
//块号,块大小,块数,块左边届,右边界,当前点跳出块的步数,跳出块的位置
void solve(){
num = n/block;
if(n%block) num++;
for(int i = 1; i <= num; i++)
r[i] = i*block;
r[num] = n;
for(int i = n; i >= 1; i--){
if(i+a[i] > r[belong[i]]){
st[i] = 1;
id[i] = i+a[i];
}else{
st[i] = st[i+a[i]]+1;
id[i] = id[i+a[i]];
}
}
}
void update(int pos,int val){
a[pos] = val;
for(int i = pos; i >= r[belong[pos]-1]; i--){
if(i+a[i] > r[belong[i]]){
st[i] = 1;
id[i] = i+a[i];
}else{
st[i] = st[i+a[i]]+1;
id[i] = id[i+a[i]];
}
}
}
int query(int pos){
int res = 0;
while(pos <= n){
res += st[pos];
pos = id[pos];
}
return res;
}
int main(){
while(~scanf("%d%d",&n,&m)){
block = (int)sqrt(n);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]),belong[i] = (i-1)/block+1;
solve();
int op,p,v;
for(int i = 1; i <= m; i++){
scanf("%d",&op);
if(op == 1){
scanf("%d",&p);
printf("%d\n",query(p));
}
if(op == 2){
scanf("%d%d",&p,&v);
update(p,v);
}
}
}
}