Code
#include <iostream>
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cstring>
using namespace std;
namespace inout
{
const int S = 1 << 20;
char frd[S], *ihed = frd + S;
const char *ital = ihed;
inline char inChar()
{
if (ihed == ital)
fread(frd, 1, S, stdin), ihed = frd;
return *ihed++;
}
inline int get()
{
char ch; int res = 0; bool flag = false;
while (!isdigit(ch = inChar()) && ch != '-');
(ch == '-' ? flag = true : res = ch ^ 48);
while (isdigit(ch = inChar()))
res = res * 10 + ch - 48;
return flag ? -res : res;
}
char fwt[S], *ohed = fwt;
const char *otal = fwt + S;
inline char outChar(char ch)
{
if (ohed == otal)
fwrite(fwt, 1, S, stdout), ohed = fwt;
return *ohed++ = ch;
}
inline void put(int x)
{
if (x > 9) put(x / 10);
outChar(x % 10 + 48);
}
};
using namespace inout;
const int N = 2e5 + 5;
int n, m, k[N];
inline int Min(int x, int y) {return x < y ? x : y;}
namespace LCT
{
int lc[N], rc[N], fa[N], sze[N], rev[N];
int qr, que[N];
inline bool Which(int x)
{
return lc[fa[x]] == x;
}
inline bool isRoot(int x)
{
return !fa[x] || lc[fa[x]] != x && rc[fa[x]] != x;
}
inline bool Uptdate(int x)
{
sze[x] = sze[lc[x]] + sze[rc[x]] + 1;
}
inline void pushDown(int x)
{
if (rev[x])
{
swap(lc[x], rc[x]);
if (lc[x]) rev[lc[x]] ^= 1;
if (rc[x]) rev[rc[x]] ^= 1;
rev[x] = 0;
}
}
inline void Rotate(int x)
{
int y = fa[x], z = fa[y],
b = lc[y] == x ? rc[x] : lc[x];
if (z && !isRoot(y))
(lc[z] == y ? lc[z] : rc[z]) = x;
fa[x] = z; fa[y] = x;
if (b) fa[b] = y;
if (lc[y] == x) rc[x] = y, lc[y] = b;
else lc[x] = y, rc[y] = b;
Uptdate(y);
}
inline void Splay(int x)
{
que[qr = 1] = x;
for (int y = x; !isRoot(y); y = fa[y]) que[++qr] = fa[y];
for (int i = qr; i; --i) pushDown(que[i]);
while (!isRoot(x))
{
if (!isRoot(fa[x]))
Which(fa[x]) == Which(x) ? Rotate(fa[x]) : Rotate(x);
Rotate(x);
}
Uptdate(x);
}
inline void Access(int x)
{
for (int y = 0; x; y = x, x = fa[x])
{
Splay(x); rc[x] = y;
if (y) fa[y] = x; Uptdate(x);
}
}
inline int findRoot(int x)
{
Access(x); Splay(x);
while (pushDown(x), lc[x]) x = lc[x];
Splay(x); return x;
}
inline void makeRoot(int x)
{
Access(x); Splay(x); rev[x] ^= 1;
}
inline void Link(int x, int y)
{
makeRoot(x); fa[x] = y;
}
inline void Cut(int x, int y)
{
makeRoot(x); Access(y); Splay(y);
lc[y] = fa[x] = 0; Uptdate(y);
}
inline int Select(int x, int y)
{
makeRoot(x); Access(y); Splay(y);
return sze[y] - 1;
}
};
using namespace LCT;
int main()
{
n = get() + 1;
for (int i = 1; i <= n; ++i) sze[i] = 1;
for (int i = 1; i < n; ++i)
k[i] = get(), Link(i, Min(i + k[i], n));
m = get(); int x, y;
while (m--)
{
x = get(); y = get() + 1;
if (x & 1)
put(Select(y, n)), outChar('\n');
else
{
Cut(y, Min(y + k[y], n));
k[y] = get();
Link(y, Min(y + k[y], n));
}
}
fwrite(fwt, 1, ohed - fwt, stdout);
return 0;
}