题意:每一个洞都有一个能量值>>>一个球可以从这个位置跳到i+a[i]的位置>>>
考虑维护球能跳到下一个的位置>>倒着维护>>则能够>>找出球的最终位置 nxt[x]
然后考虑更改的操作>>每次更改这个位置的球,我们必须更改>>他之前的所有位置
复杂度肯定要爆的>>>
考虑优化>>>我能不能将更改和查询全部转换为sqrt 或者log 级别的东西>>考虑分块>>
在分块操作中我们让每一个球每次跳过1块的距离>>
在更新的操作中需要更新一个块>>>>>>>>>
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],nxt[N],bel[N],L[N],R[N],blo,n,m,cnt;
int num[N],last[N];
void build(){
cnt=n/blo;if(n%blo) cnt++;
for(int i=1;i<=n;i++) bel[i]=(i-1)/blo+1;
for(int i=1;i<=cnt;i++) L[i]=(i-1)*blo+1,R[i]=min(n,i*blo);
}
void update(int x,int y){
if(y>n){
num[x]=1;
last[x]=x;
nxt[x]=n+1;
}
else if(bel[x]==bel[y]){
last[x]=last[y];
nxt[x]=nxt[y];
num[x]=num[y]+1;
}
else {
nxt[x]=y;
last[x]=x;
num[x]=1;
}
}
void query(int x){
int res=num[x];int end_=last[x];
while(1){
x=nxt[x];
if(x>n) break;
end_=last[x];
res+=num[x];
}
printf("%d %d\n",end_,res);
}
int main(){
scanf("%d%d",&n,&m);blo=sqrt(n);
build();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(i+a[i]>n) a[i]=n+1-i;
}
for(int i=n;i>=1;i--) update(i,i+a[i]);
int cas,x,y;
while(m--){
scanf("%d",&cas);
if(cas){
scanf("%d",&x);
query(x);
}
else{
scanf("%d%d",&x,&y);
a[x]=y;
int tmp=bel[x];
for(int i=x;i>=L[tmp];i--){
update(i,i+a[i]);
}
}
}
return 0;
}