_bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【分块】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2002
见一周目记录:http://www.cnblogs.com/ciao-sora/p/6099077.html
#include <cstdio> #include <cmath> const int maxn = 200005; int n, m, a[maxn], to[maxn], need[maxn], siz, id, t1, t2, t3, haji; inline int qry(int pos) { int rt = 0; while (~pos) { rt += need[pos]; pos = to[pos]; } return rt; } inline void upd(int pos, int val) { id = pos / siz; haji = id * siz; a[pos] = val; for (int i = pos; i >= haji; --i) { if (i + a[i] >= n) { to[i] = -1; need[i] = 1; } else if (i + a[i] >= (id + 1) * siz) { to[i] = i + a[i]; need[i] = 1; } else { to[i] = to[i + a[i]]; need[i] = need[i + a[i]] + 1; } } } int main(void) { scanf("%d", &n); siz = (int)sqrt((float)n + 0.5f); for (int i = 0; i < n; ++i) { scanf("%d", a + i); } for (int i = n - 1; ~i; --i) { id = i / siz; if (i + a[i] >= n) { to[i] = -1; need[i] = 1; } else if (i + a[i] >= (id + 1) * siz) { to[i] = i + a[i]; need[i] = 1; } else { to[i] = to[i + a[i]]; need[i] = need[i + a[i]] + 1; } } scanf("%d", &m); while (m--) { scanf("%d%d", &t1, &t2); if (t1 == 1) { printf("%d\n", qry(t2)); } else { scanf("%d", &t3); upd(t2, t3); } } return 0; }