和上一题差不多,就只查询了次数,不用输出跳出前的最后一位
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-7; const int N=400000+10,maxn=60000+10,inf=0x3f3f3f3f; int n,m,block,num; int l[N],r[N],belong[N]; int Next[N],cnt[N],a[N]; void build() { block=(int)sqrt(n+0.5); 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; for(int i=1;i<=n;i++) belong[i]=(i-1)/block+1; for(int i=n;i>=1;i--) { int p=i,f=0; cnt[i]=1; while(belong[p+a[p]]==belong[p]) { if(Next[p+a[p]]) { cnt[i]=cnt[p+a[p]]+1; Next[i]=Next[p+a[p]]; f=1; break; } cnt[i]++; p=p+a[p]; if(p+a[p]>n)break; } if(!f)Next[i]=p+a[p]; } } void update(int x,int y) { a[x]=y; for(int i=r[belong[x]];i>=l[belong[x]];i--) { int p=i,f=0; cnt[i]=1; while(belong[p+a[p]]==belong[p]) { if(Next[p+a[p]]) { cnt[i]=cnt[p+a[p]]+1; Next[i]=Next[p+a[p]]; f=1; break; } cnt[i]++; p=p+a[p]; if(p+a[p]>n)break; } if(!f)Next[i]=p+a[p]; } } void query(int x) { int ans=1; while(x<=n) { if(Next[x]>n) { while(x+a[x]<=n)ans++,x=x+a[x]; break; } else { ans+=cnt[x]; x=Next[x]; } } printf("%d ",ans); } void debug() { for(int i=1;i<=n;i++) printf("%d %d ",Next[i],cnt[i]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); build(); // debug(); scanf("%d",&m); while(m--) { int x,y; scanf("%d",&x); if(x==2) { scanf("%d%d",&x,&y); x++; update(x,y); } else { scanf("%d",&x); x++; query(x); } // debug(); } return 0; } /******************** ********************/