链接
题目描述
思路
分块,在一个块内就直接处理,修改也是只改一个块的就可以了
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll n, m, ans;
ll a[200005], step[200005], to[200005];
ll l[5005], r[5005], belong[200005];
ll read()
{
ll re = 0;
char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while('0' <= ch && ch <= '9') {
re = re * 10 + ch - 48;
ch = getchar();
}
return re;
}
int main()
{
// freopen("P3203_1.in","r",stdin);
n = read();
ll size = sqrt(n);
ll num = n / size;
if(n % size != 0) num++;
for(int i = 1; i <= n; ++i)
a[i] = read();
for(int i = 1; i <= num; ++i)
l[i] = r[i - 1] + 1, r[i] = l[i] + size - 1;
r[num] = n;
for(int j = 1, i = 1; i <= num; ++j)
{
belong[j] = i;
if(j == r[i]) ++i;
}
for(int i = n; i >= 1; --i)//从后往前去修改
{
to[i] = i + a[i];
if(to[i] > r[belong[i]]) step[i] = 1;
else step[i] = step[to[i]] + 1, to[i] = to[to[i]];
}
m = read();
for(int i = 1; i <= m; ++i)
{
int type = read();
if(type == 1) {
ans = 0;
int x = read(); x++;
while(x <= n) ans += step[x], x = to[x];
printf("%lld\n", ans);
}
else {
int x = read();
ll y = read();
x++;
a[x] = y;
for(int i = r[belong[x]]; i >= l[belong[x]]; --i)
{
to[i] = i + a[i];
if(to[i] > r[belong[i]]) step[i] = 1;
else step[i] = step[to[i]] + 1, to[i] = to[to[i]];
}
}
}
return 0;
}