非常裸的裸题……
很明显每个点跳到的点的编号一定大于当前点,那么整个跳的图就形成了一个树结构,每个点的父亲节点定义为min(i+k,n)
这样搞之后,操作1就是查询某个点的深度,操作2就是换父亲
大概可以用dfs序搞
/∗ 这个坑以后再填好了 ∗/
反正只有换父亲嘛。。。来发lct就好啦2333
作死地写了单旋然后T掉了= =
#include <bits/stdc++.h>
using namespace std;
#define For(i,a,b) for(int i=a;i<b;i++)
#define lc ch[u][0]
#define rc ch[u][1]
#define maxn 200003
inline int rd() {
char c = getchar();
while (!isdigit(c)) c = getchar() ; int x = c - '0';
while (isdigit(c = getchar())) x = x * 10 + c - '0';
return x;
}
typedef int arr[maxn];
arr fa , size , rv , sta;
int ch[maxn][2] , top , n , m;
inline bool isrt(int u) { return (ch[fa[u]][0] != u) && (ch[fa[u]][1] != u) ; }
inline void mt(int u) { if (u) size[u] = 1 + (lc ? size[lc] : 0) + (rc ? size[rc] : 0) ; }
inline void ps(int u) { if (u && rv[u]) swap(lc , rc) , rv[lc] ^= 1 , rv[rc] ^= 1 , rv[u] = 0; }
inline void rot(int u) {
int f = fa[u] , g = fa[f] , l , r;
l = (ch[f][1] == u) , r = l ^ 1;
if (!isrt(f)) ch[g][ch[g][1] == f] = u;
fa[u] = g , fa[f] = u;if (ch[u][r]) fa[ch[u][r]] = f;
ch[f][l] = ch[u][r] , ch[u][r] = f;
mt(f) , mt(u);
}
inline void clear(int u) {
for(sta[top ++] = u;!isrt(u);u = fa[u]) sta[top ++] = fa[u];
for(;top;) ps(sta[-- top]);
}
inline void splay(int u) {
for(clear(u);!isrt(u);rot(u)) {
int f = fa[u] , g = fa[f];
if (!isrt(f)) rot(((ch[f][1] == u) ^ (ch[g][1] == f)) ? u : f);
}
mt(u);
}
inline void access(int u) {
int v = u;
for(int t = 0;u;t = u , u = fa[u])
splay(u) , rc = t ;
splay(v);
}
inline void mkrt(int u) { access(u) ; rv[u] ^= 1 ; ps(u) ; }
inline void link(int u , int v) { mkrt(u) , fa[u] = v ; }
inline void cut(int u) {
mkrt(n + 1);
access(u);
fa[lc] = 0 , lc = 0 , mt(u);
}
inline int get_dep(int u) {
mkrt(u);
access(n + 1);
return size[n + 1] - 1;
}
inline int get_par(int u , int k) { u += k ; if (u > n) u = n + 1 ; return u ; }
int main() {
#ifndef ONLINE_JUDGE
freopen("data.txt" , "r" , stdin);
freopen("data.out" , "w" , stdout);
#endif
n = rd();
For(i , 1 , n + 1) link(i , get_par(i , rd()));
m = rd();
For(i , 0 , m) {
int a = rd() , b = rd() + 1 , c;
if (a == 2) {
c = rd();
cut(b);
link(b , get_par(b , c));
} else
printf("%d\n" , get_dep(b));
}
return 0;
}