某道题要求树上 \(k\) 级祖先,然后我发现我不会长剖,学了一下,感觉会了重剖之后长剖很好理解。
但是我为什么不会长剖呢?
先鸽着。
练习 代码 板题(洛谷)//12252024832524
#include <cstdio>
#include <cstring>
#include <algorithm>
#define TT template<typename T>
using namespace std;
typedef long long LL;
const int MAXN = 500005;
int n,Q;
LL Read()
{
LL x = 0,f = 1;char c = getchar();
while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
return x * f;
}
TT void Put1(T x)
{
if(x > 9) Put1(x/10);
putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
if(x < 0) putchar('-'),x = -x;
Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}
#define ui unsigned int
ui S;
inline ui Get() {
S ^= S << 13;
S ^= S >> 17;
S ^= S << 5;
return S;
}
int head[MAXN],tot;
struct edge
{
int v,nxt;
}e[MAXN];
void Add_Edge(int x,int y)
{
e[++tot].v = y;
e[tot].nxt = head[x];
head[x] = tot;
}
int f[MAXN][19],d[MAXN],LG[MAXN],rt,son[MAXN],MD[MAXN];
void dfs1(int x)
{
MD[x] = d[x] = d[f[x][0]] + 1;
for(int i = 1;i <= LG[d[x]];++ i) f[x][i] = f[f[x][i-1]][i-1];
for(int i = head[x]; i ;i = e[i].nxt)
{
dfs1(e[i].v);
MD[x] = Max(MD[x],MD[e[i].v]);
if(MD[e[i].v] > MD[son[x]]) son[x] = e[i].v;
}
}
int dfn[MAXN],dfntot,U[MAXN],D[MAXN],tp[MAXN];
void dfs2(int x,int t)
{
if(x == t) tp[x] = x;
else tp[x] = tp[f[x][0]];
dfn[x] = ++dfntot;
U[dfntot] = t; D[dfntot] = x;
if(!son[x]) return;
dfs2(son[x],f[t][0]);
for(int i = head[x]; i ;i = e[i].nxt)
if(e[i].v^son[x])
dfs2(e[i].v,e[i].v);
}
int Query(int u,int k)
{
if(!k) return u;
u = f[u][LG[k]]; k -= 1<<LG[k];
k -= d[u] - d[tp[u]]; u = tp[u];
if(k >= 0) return U[dfn[u]+k];
else return D[dfn[u]-k];
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n = Read(); Q = Read(); S = Read();
LG[0] = -1;
for(int i = 1;i <= n;++ i) LG[i] = LG[i>>1] + 1;
for(int i = 1;i <= n;++ i)
if((f[i][0] = Read())) Add_Edge(f[i][0],i);
else rt = i;
dfs1(rt);
dfs2(rt,rt);
LL ans = 0,lst = 0;
for(int i = 1;i <= Q;++ i)
{
int u = (Get()^lst) % n + 1;
int k = (Get()^lst) % d[u];
lst = Query(u,k);
ans ^= lst * i;
}
Put(ans);
return 0;
}