[HNOI2010]弹飞绵羊
题目链接
题解
不会lct(好想学啊T_T)
分块
记录每个点跳出当前块需要的步数和跳出块到达的点
Code
#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std;
inline int gi() {
RG int x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
return f ? -x : x;
}
int n, block;
const int N = 200010;
int l[N], r[N], K[N], st[N], pt[N], belong[N], cnt;
inline int calc(int x) {
int tmp = 0;
while (x) {
tmp += st[x];
x = pt[x];
}
return tmp;
}
int main() {
n = gi(); block = sqrt(n);
for (int i = 1; i <= n; i++) K[i] = gi();
if (n%block) cnt = n/block+1;
else cnt = n/block;
for (int i = 1; i <= n; i++)
belong[i] = (i-1)/block+1;
for (int i = 1; i <= cnt; i++)
l[i] = block*(i-1)+1, r[i] = block*i;
r[cnt] = n;
for (int i = n; i > 0; i--)
if (belong[i] == belong[i+K[i]]) st[i] = st[i+K[i]]+1, pt[i] = pt[i+K[i]];
else st[i] = 1, pt[i] = K[i]+i;
int m = gi();
while (m--) {
int type = gi(), x = gi()+1;
if (type == 1) printf("%d\n", calc(x));
else {
int y = gi(); K[x] = y;
for (int i = x; i >= l[belong[x]]; i--)
if (belong[i] == belong[i+K[i]]) st[i] = st[i+K[i]]+1, pt[i] = pt[i+K[i]];
else st[i] = 1, pt[i] = K[i]+i;
}
}
return 0;
}