http://www.lydsy.com/JudgeOnline/problem.php?id=2002
分块基础题,初次接触,很巧妙。
OJ好像挂了,没法提交。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int a[200005],cnt[200005],next[200005],l[1000],r[1000],belong[200005],n,m; void build() { int block = sqrt(n); int 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 temp = i+a[i]; if(temp > n) { cnt[i] = 1; next[i] = -1; } else if(belong[i] == belong[temp]) { cnt[i] = cnt[temp]+1; next[i] = next[temp]; } else { cnt[i] = 1; next[i] = temp; } } } int getsum(int x) { int ans = cnt[x]; while(next[x] > 0) { x = next[x]; ans += cnt[x]; } return ans; } void update(int x,int y) { a[x] = y; for(int i = x;i >= l[belong[x]];i--) { int temp = i+a[i]; if(temp > n) { cnt[i] = 1; next[i] = -1; } else if(belong[i] == belong[temp]) { cnt[i] = cnt[temp]+1; next[i] = next[temp]; } else { cnt[i] = 1; next[i] = temp; } } } int main() { scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); build(); scanf("%d",&m); while(m--) { int i,j,k; scanf("%d%d",&i,&j); if(i == 1) printf("%d ",getsum(j+1)); else { scanf("%d",&k); update(j+1,k); } } return 0; }