【莫队算法】
〖相关资料〗
〖相关题目〗
1.【bzoj2038】[2009国家集训队]小Z的袜子(hose)
题意:给出n个数与m个区间,在每个区间内选出两个数,求选出的两个数相等的概率。
分析:hzwerの博客
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 const int N=5e4+5; 8 int n,m,s[N],c[N],pos[N]; 9 LL ans; 10 struct node{int id,l,r;LL a,b;}a[N]; 11 int read() 12 { 13 int x=0,f=1;char c=getchar(); 14 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 15 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 16 return x*f; 17 } 18 bool cmp(node a,node b) 19 { 20 if(pos[a.l]==pos[b.l])return a.r<b.r; 21 return a.l<b.l; 22 } 23 bool cmp2(node a,node b){return a.id<b.id;} 24 LL sqr(int x){return 1ll*x*x;} 25 LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);} 26 void update(int p,int val) 27 { 28 ans-=sqr(s[c[p]]); 29 s[c[p]]+=val; 30 ans+=sqr(s[c[p]]); 31 } 32 int main() 33 { 34 n=read();m=read(); 35 for(int i=1;i<=n;i++)c[i]=read(); 36 int block=(int)sqrt(n); 37 for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1; 38 for(int i=1;i<=m;i++) 39 a[i].l=read(),a[i].r=read(),a[i].id=i; 40 sort(a+1,a+m+1,cmp); 41 for(int i=1,l=1,r=0;i<=m;i++) 42 { 43 for(;r<a[i].r;r++)update(r+1,1); 44 for(;r>a[i].r;r--)update(r,-1); 45 for(;l<a[i].l;l++)update(l,-1); 46 for(;l>a[i].l;l--)update(l-1,1); 47 if(a[i].l==a[i].r){a[i].a=0;a[i].b=1;continue;} 48 a[i].a=ans-(a[i].r-a[i].l+1); 49 a[i].b=1ll*(a[i].r-a[i].l+1)*(a[i].r-a[i].l); 50 LL k=gcd(a[i].a,a[i].b); 51 a[i].a/=k;a[i].b/=k; 52 } 53 sort(a+1,a+m+1,cmp2); 54 for(int i=1;i<=m;i++)printf("%lld/%lld ",a[i].a,a[i].b); 55 return 0; 56 }
2.【bzoj3052】[wc2013]糖果公园
题意:见原题
分析:vfleakingの博客
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 const int N=1e5+5; 8 int n,m,Q,cnt,op,x,y,B,ind; 9 int v[N],w[N],c[N],pre[N],num[N]; 10 int first[N],dfn[N],deep[N],fa[N][17]; 11 int tot,top,st[N],be[N]; 12 LL ans,sum[N]; 13 bool vis[N]; 14 struct edge{int to,next;}e[N<<1]; 15 struct change{int x,y,pre;}a[N]; 16 struct query{int x,y,t,id;}b[N]; 17 const int M=1e5; 18 char ib[M+7],*ip=ib+M; 19 int G() 20 { 21 if(ip==ib+M)fread(ip=ib,1,M,stdin)[ib]=0; 22 return *ip++; 23 } 24 int read() 25 { 26 int x=0,f=1; 27 if(ip<ib+M-100) 28 { 29 while(*ip<48)*ip++=='-'?f=-1:0; 30 while(*ip>47)x=x*10+*ip++-48; 31 } 32 else 33 { 34 int c=G(); 35 while(c<48)c=='-'?f=-1:0,c=G(); 36 while(c>47)x=x*10+c-48,c=G(); 37 } 38 return x*f; 39 } 40 bool cmp(query a,query b) 41 { 42 if(be[a.x]==be[b.x]&&be[a.y]==be[b.y])return a.t<b.t; 43 if(be[a.x]==be[b.x])return be[a.y]<be[b.y]; 44 return be[a.x]<be[b.x]; 45 } 46 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;} 47 void dfs(int x) 48 { 49 dfn[x]=++ind; 50 for(int i=1;(1<<i)<=deep[x];i++) 51 fa[x][i]=fa[fa[x][i-1]][i-1]; 52 int bottom=top; 53 for(int i=first[x];i;i=e[i].next) 54 { 55 int to=e[i].to; 56 if(to==fa[x][0])continue; 57 deep[to]=deep[x]+1; 58 fa[to][0]=x;dfs(to); 59 if(top-bottom>=B) 60 { 61 tot++; 62 while(top!=bottom)be[st[top--]]=tot; 63 } 64 } 65 st[++top]=x; 66 } 67 int lca(int x,int y) 68 { 69 if(deep[x]<deep[y])swap(x,y); 70 int d=deep[x]-deep[y]; 71 for(int i=0;(1<<i)<=d;i++) 72 if((1<<i)&d)x=fa[x][i]; 73 if(x==y)return x; 74 for(int i=16;i>=0;i--) 75 if(fa[x][i]!=fa[y][i]) 76 x=fa[x][i],y=fa[y][i]; 77 return fa[x][0]; 78 } 79 void rev(int x) 80 { 81 if(vis[x])ans-=1ll*w[num[c[x]]]*v[c[x]],num[c[x]]--; 82 else num[c[x]]++,ans+=1ll*w[num[c[x]]]*v[c[x]]; 83 vis[x]^=1; 84 } 85 void modify(int x,int y) 86 { 87 if(!vis[x])c[x]=y; 88 else {rev(x);c[x]=y;rev(x);} 89 } 90 void solve(int x,int y) 91 { 92 while(x!=y) 93 { 94 if(deep[x]>deep[y])rev(x),x=fa[x][0]; 95 else rev(y),y=fa[y][0]; 96 } 97 } 98 int main() 99 { 100 n=read();m=read();Q=read(); 101 for(int i=1;i<=m;i++)v[i]=read(); 102 for(int i=1;i<=n;i++)w[i]=read(); 103 for(int i=1;i<n;i++) 104 { 105 x=read();y=read(); 106 ins(x,y);ins(y,x); 107 } 108 for(int i=1;i<=n;i++)pre[i]=c[i]=read(); 109 B=pow(n,2.0/3)*0.5;dfs(1); 110 while(top)be[st[top--]]=tot; 111 int c0=0,c1=0; 112 for(int i=1;i<=Q;i++) 113 { 114 op=read();x=read();y=read(); 115 if(!op)a[++c0]=(change){x,y,pre[x]},pre[x]=y; 116 else 117 { 118 if(dfn[x]>dfn[y])swap(x,y); 119 b[++c1]=(query){x,y,c0,c1}; 120 } 121 } 122 sort(b+1,b+c1+1,cmp); 123 for(int i=1;i<=b[1].t;i++)modify(a[i].x,a[i].y); 124 solve(b[1].x,b[1].y); 125 int t=lca(b[1].x,b[1].y); 126 rev(t);sum[b[1].id]=ans;rev(t); 127 for(int i=2;i<=c1;i++) 128 { 129 for(int j=b[i-1].t+1;j<=b[i].t;j++)modify(a[j].x,a[j].y); 130 for(int j=b[i-1].t;j>b[i].t;j--)modify(a[j].x,a[j].pre); 131 solve(b[i-1].x,b[i].x); 132 solve(b[i-1].y,b[i].y); 133 t=lca(b[i].x,b[i].y); 134 rev(t);sum[b[i].id]=ans;rev(t); 135 } 136 for(int i=1;i<=c1;i++)printf("%lld ",sum[i]); 137 return 0; 138 }
3.【bzoj4129】Haruna’s Breakfast
题意:见原题
分析:无。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 const int N=5e4+5; 8 int n,m,cnt,op,x,y,B,S,ind; 9 int top,tot,be[N],st[N]; 10 int first[N],c[N],pre[N],ans[N]; 11 int dfn[N],deep[N],fa[N][17]; 12 int blo,numb[N],sz[N],num[N],fir[N]; 13 bool vis[N]; 14 struct edge{int to,next;}e[N<<1]; 15 struct change{int x,y,pre;}a[N]; 16 struct query{int x,y,t,id;}b[N]; 17 int read() 18 { 19 int x=0,f=1;char c=getchar(); 20 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 21 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 22 return x*f; 23 } 24 bool cmp(query a,query b) 25 { 26 if(be[a.x]==be[b.x]&&be[a.y]==be[b.y])return a.t<b.t; 27 if(be[a.x]==be[b.x])return be[a.y]<be[b.y]; 28 return be[a.x]<be[b.x]; 29 } 30 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;} 31 void dfs(int x) 32 { 33 dfn[x]=++ind; 34 for(int i=1;(1<<i)<=deep[x];i++) 35 fa[x][i]=fa[fa[x][i-1]][i-1]; 36 int bottom=top; 37 for(int i=first[x];i;i=e[i].next) 38 { 39 int to=e[i].to; 40 if(to==fa[x][0])continue; 41 deep[to]=deep[x]+1; 42 fa[to][0]=x;dfs(to); 43 if(top-bottom>=B) 44 { 45 tot++; 46 while(top!=bottom)be[st[top--]]=tot; 47 } 48 } 49 st[++top]=x; 50 } 51 int lca(int x,int y) 52 { 53 if(deep[x]<deep[y])swap(x,y); 54 int d=deep[x]-deep[y]; 55 for(int i=0;(1<<i)<=d;i++) 56 if((1<<i)&d)x=fa[x][i]; 57 if(x==y)return x; 58 for(int i=16;i>=0;i--) 59 if(fa[x][i]!=fa[y][i]) 60 x=fa[x][i],y=fa[y][i]; 61 return fa[x][0]; 62 } 63 void rev(int x) 64 { 65 if(c[x]>n){vis[x]^=1;return;} 66 int id=numb[c[x]]; 67 if(vis[x])num[c[x]]--,sz[id]+=(num[c[x]]==0); 68 else sz[id]-=(num[c[x]]==0),num[c[x]]++; 69 vis[x]^=1; 70 } 71 void modify(int x,int y) 72 { 73 if(!vis[x])c[x]=y; 74 else {rev(x);c[x]=y;rev(x);} 75 } 76 void solve(int x,int y) 77 { 78 while(x!=y) 79 { 80 if(deep[x]>deep[y])rev(x),x=fa[x][0]; 81 else rev(y),y=fa[y][0]; 82 } 83 } 84 int calc() 85 { 86 int id=0; 87 for(int i=1;i<=blo;i++) 88 if(sz[i]){id=i;break;} 89 for(int i=fir[id];i<=n&&numb[i]==id;i++) 90 if(!num[i])return i; 91 return 0; 92 } 93 int main() 94 { 95 n=read();m=read(); 96 for(int i=1;i<=n;i++)pre[i]=c[i]=read(); 97 for(int i=1;i<n;i++) 98 { 99 x=read();y=read(); 100 ins(x,y);ins(y,x); 101 } 102 S=sqrt(n);blo=1; 103 numb[0]=1;sz[1]++;fir[1]=0; 104 for(int i=1;i<=n;i++) 105 { 106 numb[i]=(i-1)/S+1; 107 if(!sz[numb[i]])fir[numb[i]]=i; 108 sz[numb[i]]++; 109 blo=max(blo,numb[i]); 110 } 111 B=pow(n,2.0/3)*0.5;dfs(1); 112 while(top)be[st[top--]]=tot; 113 int c0=0,c1=0; 114 for(int i=1;i<=m;i++) 115 { 116 op=read();x=read();y=read(); 117 if(!op)a[++c0]=(change){x,y,pre[x]},pre[x]=y; 118 else 119 { 120 if(dfn[x]>dfn[y])swap(x,y); 121 b[++c1]=(query){x,y,c0,c1}; 122 } 123 } 124 sort(b+1,b+c1+1,cmp); 125 for(int i=1;i<=b[1].t;i++)modify(a[i].x,a[i].y); 126 solve(b[1].x,b[1].y); 127 int t=lca(b[1].x,b[1].y); 128 rev(t);ans[b[1].id]=calc();rev(t); 129 for(int i=2;i<=c1;i++) 130 { 131 for(int j=b[i-1].t+1;j<=b[i].t;j++)modify(a[j].x,a[j].y); 132 for(int j=b[i-1].t;j>b[i].t;j--)modify(a[j].x,a[j].pre); 133 solve(b[i-1].x,b[i].x); 134 solve(b[i-1].y,b[i].y); 135 t=lca(b[i].x,b[i].y); 136 rev(t);ans[b[i].id]=calc();rev(t); 137 } 138 for(int i=1;i<=c1;i++)printf("%d ",ans[i]); 139 return 0; 140 }
【树分块】
〖相关题目〗
1.【bzoj1086】[SCOI2005]王室联邦
题意:给定一棵树,要求将这棵树分成一些块,使每块大小在[B,3B]之间。
分析:PoPoQQQの博客
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 const int N=1e3+5; 8 int n,B,x,y,cnt,tot,top; 9 int first[N],st[N],be[N],root[N]; 10 struct edge{int to,next;}e[N<<1]; 11 int read() 12 { 13 int x=0,f=1;char c=getchar(); 14 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 15 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 16 return x*f; 17 } 18 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;} 19 void dfs(int x,int fa) 20 { 21 int bottom=top; 22 for(int i=first[x];i;i=e[i].next) 23 { 24 int to=e[i].to; 25 if(to==fa)continue; 26 dfs(to,x); 27 if(top-bottom>=B) 28 { 29 root[++tot]=x; 30 while(top!=bottom)be[st[top--]]=tot; 31 } 32 } 33 st[++top]=x; 34 } 35 int main() 36 { 37 n=read();B=read(); 38 for(int i=1;i<n;i++)x=read(),y=read(),ins(x,y),ins(y,x); 39 dfs(1,-1); 40 while(top)be[st[top--]]=tot; 41 printf("%d ",tot); 42 for(int i=1;i<=n;i++)printf("%d ",be[i]); 43 printf(" "); 44 for(int i=1;i<=tot;i++)printf("%d ",root[i]); 45 return 0; 46 }
【分块】
〖相关题目〗
1.【codevs5037】线段树练习4加强版
题意:维护一个序列,支持2种操作:add a b c:区间[a,b]中每个数加上c;count a b:查询区间[a,b]中有多少数是k的倍数(k为给定常数)。
分析:无
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 const int N=2e5+5; 8 const int M=455; 9 int n,m,k,s,id,l,r,c; 10 int a[N],add[M],f[M][N]; 11 char op[6]; 12 int read() 13 { 14 int x=0,f=1;char c=getchar(); 15 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 16 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 17 return x*f; 18 } 19 void modify() 20 { 21 c=read();id=(l-1)/s+1; 22 for(int i=l;i<=min(id*s,r);i++) 23 { 24 f[id][a[i]]--; 25 a[i]=(a[i]+c)%k; 26 f[id][a[i]]++; 27 } 28 l=id;id=(r-1)/s+1; 29 for(int i=max(l,id-1)*s+1;i<=r;i++) 30 { 31 f[id][a[i]]--; 32 a[i]=(a[i]+c)%k; 33 f[id][a[i]]++; 34 } 35 r=id; 36 for(int i=l+1;i<r;i++)add[i]=(add[i]+c)%k; 37 } 38 int query() 39 { 40 int ans=0; 41 id=(l-1)/s+1; 42 for(int i=l;i<=min(id*s,r);i++) 43 if((a[i]+add[id])%k==0)ans++; 44 l=id;id=(r-1)/s+1; 45 for(int i=max(l,id-1)*s+1;i<=r;i++) 46 if((a[i]+add[id])%k==0)ans++; 47 r=id; 48 for(int i=l+1;i<r;i++)ans+=f[i][(k-add[i])%k]; 49 return ans; 50 } 51 int main() 52 { 53 n=read();s=sqrt(n); 54 m=read();k=read(); 55 for(int i=1;i<=n;i++) 56 { 57 a[i]=read()%k; 58 id=(i-1)/s+1; 59 f[id][a[i]]++; 60 } 61 while(m--) 62 { 63 scanf("%s",op); 64 l=read();r=read(); 65 if(op[0]=='a')modify(); 66 else printf("%d ",query()); 67 } 68 return 0; 69 }
2.【bzoj2724】[Violet 6]蒲公英
题意:求区间众数。
分析:hzwer的博客
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<vector> 6 #define LL long long 7 using namespace std; 8 const int N=4e4+5; 9 const int M=205; 10 int n,m,s,tot,l,r,ans; 11 int a[N],b[N],be[N],cnt[N],f[M][M]; 12 vector<int> p[N]; 13 int read() 14 { 15 int x=0,f=1;char c=getchar(); 16 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 17 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 18 return x*f; 19 } 20 void pre(int x) 21 { 22 memset(cnt,0,sizeof(cnt)); 23 int mx=0,ans=0,t; 24 for(int i=(x-1)*s+1;i<=n;i++) 25 { 26 cnt[a[i]]++;t=be[i]; 27 if(cnt[a[i]]>mx||(cnt[a[i]]==mx&&a[i]<ans)) 28 mx=cnt[a[i]],ans=a[i]; 29 f[x][t]=ans; 30 } 31 } 32 int query(int l,int r,int x) 33 { 34 l=lower_bound(p[x].begin(),p[x].end(),l)-p[x].begin(); 35 r=upper_bound(p[x].begin(),p[x].end(),r)-p[x].begin(); 36 return r-l; 37 } 38 int work() 39 { 40 int ans=f[be[l]+1][be[r]-1],mx=query(l,r,ans),t; 41 for(int i=l;i<=min(be[l]*s,r);i++) 42 { 43 t=query(l,r,a[i]); 44 if(t>mx||(t==mx&&a[i]<ans))mx=t,ans=a[i]; 45 } 46 if(be[l]==be[r])return ans; 47 for(int i=(be[r]-1)*s+1;i<=r;i++) 48 { 49 t=query(l,r,a[i]); 50 if(t>mx||(t==mx&&a[i]<ans))mx=t,ans=a[i]; 51 } 52 return ans; 53 } 54 int main() 55 { 56 n=read();m=read();s=sqrt(n); 57 for(int i=1;i<=n;i++)a[i]=b[i]=read(); 58 sort(b+1,b+n+1); 59 tot=unique(b+1,b+n+1)-b-1; 60 for(int i=1;i<=n;i++) 61 { 62 a[i]=lower_bound(b+1,b+tot+1,a[i])-b; 63 p[a[i]].push_back(i); 64 be[i]=(i-1)/s+1; 65 } 66 for(int i=1;i<=be[n];i++)pre(i); 67 for(int i=1;i<=m;i++) 68 { 69 l=read();r=read(); 70 l=(l+ans-1)%n+1;r=(r+ans-1)%n+1; 71 if(l>r)swap(l,r); 72 ans=b[work()]; 73 printf("%d ",ans); 74 } 75 return 0; 76 }
3.【bzoj2388】旅行规划
题意:见原题
分析:hzwerの博客
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 const int N=1e5+5; 8 const int M=325; 9 const LL inf=1e16; 10 int n,m,s,cnt,op,l,r,x,y; 11 int be[N],st[M],ed[M],num[M]; 12 int top,sta[N],t[M][M]; 13 LL tmp,k,a[N],fir[N],dif[N],add[N]; 14 int read() 15 { 16 int x=0,f=1;char c=getchar(); 17 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 18 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 19 return x*f; 20 } 21 double sl(int x,int y){return 1.0*(a[x]-a[y])/(y-x);} 22 LL get(int x) 23 { 24 if(x==0||x==n+1)return -inf; 25 int t=be[x]; 26 return a[x]+fir[t]+dif[t]*(x-st[t])+add[t]; 27 } 28 void build(int x) 29 { 30 top=0;sta[++top]=st[x]; 31 for(int i=st[x]+1;i<=ed[x];i++) 32 { 33 while(top>1&&sl(sta[top-1],sta[top])>sl(sta[top],i))top--; 34 sta[++top]=i; 35 } 36 sta[0]=0;sta[top+1]=n+1;num[x]=top; 37 for(int i=0;i<=top+1;i++)t[x][i]=sta[i]; 38 } 39 void pushdown(int x) 40 { 41 LL tmp=fir[x]; 42 for(int i=st[x];i<=ed[x];i++) 43 a[i]+=tmp+add[x],tmp+=dif[x]; 44 fir[x]=dif[x]=add[x]=0; 45 } 46 void modify() 47 { 48 k=read();l=be[x];r=be[y]; 49 tmp=k*(st[l+1]-x+1); 50 for(int i=l+1;i<r;i++) 51 fir[i]+=tmp,dif[i]+=k,tmp+=s*k; 52 pushdown(l);tmp=k; 53 for(int i=x;i<=min(ed[l],y);i++)a[i]+=tmp,tmp+=k; 54 build(l);pushdown(r); 55 tmp=k*(st[r]-x+1); 56 for(int i=max(ed[l]+1,st[r]);i<=y;i++)a[i]+=tmp,tmp+=k; 57 tmp=k*(y-x+1); 58 for(int i=y+1;i<=ed[r];i++)a[i]+=tmp; 59 build(r); 60 for(int i=r+1;i<=cnt;i++)add[i]+=tmp; 61 } 62 LL ask(int x) 63 { 64 int l=1,r=num[x],ans=0,mid; 65 while(l<=r) 66 { 67 mid=(l+r)>>1; 68 if(sl(t[x][mid-1],t[x][mid])<dif[x])ans=t[x][mid],l=mid+1; 69 else r=mid-1; 70 } 71 return get(ans); 72 } 73 LL query() 74 { 75 l=be[x];r=be[y];LL ans=-inf; 76 for(int i=l+1;i<r;i++)ans=max(ans,ask(i)); 77 for(int i=x;i<=min(ed[l],y);i++)ans=max(ans,get(i)); 78 for(int i=max(ed[l]+1,st[r]);i<=y;i++)ans=max(ans,get(i)); 79 return ans; 80 } 81 int main() 82 { 83 n=read();s=sqrt(n); 84 for(int i=1;i<=n;i++) 85 { 86 x=read();a[i]=a[i-1]+x; 87 be[i]=(i-1)/s+1; 88 } 89 cnt=be[n]; 90 a[0]=a[n+1]=-inf; 91 for(int i=1;i<=cnt;i++) 92 { 93 st[i]=(i-1)*s+1; 94 ed[i]=min(i*s,n); 95 build(i); 96 } 97 m=read(); 98 while(m--) 99 { 100 op=read();x=read();y=read(); 101 if(!op)modify(); 102 else printf("%lld ",query()); 103 } 104 return 0; 105 }
4.【bzoj2002】弹飞绵羊
题意:见原题
分析:Zsnuoの博客
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int N=200050; 7 int n,m,num,pl,w,bl,cnt; 8 int k[N],be[N],st[N],to[N]; 9 int read() 10 { 11 int x=0,f=1;char c=getchar(); 12 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 13 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 14 return x*f; 15 } 16 int ask(int t) 17 { 18 int ans=st[t]; 19 while(to[t]<=n) 20 { 21 t=to[t]; 22 ans+=st[t]; 23 } 24 return ans; 25 } 26 int main() 27 { 28 n=read();bl=sqrt(n); 29 if(n%bl)cnt=n/bl+1; 30 else cnt=n/bl; 31 for(int i=1;i<=n;i++) 32 { 33 k[i]=read(); 34 be[i]=(i-1)/bl+1; 35 } 36 for(int i=n;i>0;i--) 37 { 38 if(be[i]==be[i+k[i]]){st[i]=st[i+k[i]]+1;to[i]=to[i+k[i]];} 39 else {st[i]=1;to[i]=i+k[i];} 40 } 41 m=read(); 42 while(m--) 43 { 44 num=read();pl=read()+1; 45 if(num==1)printf("%d ",ask(pl)); 46 else 47 { 48 w=read(); 49 k[pl]=w; 50 int l=(be[pl]-1)*bl+1; 51 for(int i=pl;i>=l;i--) 52 { 53 if(be[i]==be[i+k[i]]){st[i]=st[i+k[i]]+1;to[i]=to[i+k[i]];} 54 else {st[i]=1;to[i]=i+k[i];} 55 } 56 } 57 } 58 return 0; 59 }