目前用的cin,肯定会TLE,但是小数据不知为何WA了。
#include<iostream>
using namespace std;
long long n, m, S, ans, lastans, root, head[5000005], tot, siz[5000005], id[5000005], seg[50000005], top[5000005], fa[5000005], son[5000005], cnt, deep[5000005];
inline unsigned int get(unsigned int x)
{
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return S = x;
}
struct node
{
int y, nex;
}s[5000005];
void add(int i, int j)
{
s[++tot].y = j, s[tot].nex = head[i];
head[i] = tot;
}
void dfs1(int now, int father)
{
int nowson = -1;
fa[now] = father;
siz[now] = 1;
deep[now] = deep[father] + 1;
for (int i = head[now]; i; i = s[i].nex)
{
int y = s[i].y;
if (y == father)
continue;
dfs1(y, now);
siz[now] += siz[y];
if (siz[y] > nowson)
nowson = siz[y], son[now] = y;
}
}
void dfs2(int now, int topf)
{
top[now] = topf;
id[now] = ++cnt;
seg[cnt] = now;
if (!son[now])
return;
dfs2(son[now], topf);
for (int i = head[now]; i; i = s[i].nex)
{
int y = s[i].y;
if (y == fa[now] || y == son[now])
return;
dfs2(y, y);
}
}
int query(int now, int k)
{
while (k >= id[now] - id[top[now]] + 1 && now != root)
{
k -= (id[now] - id[top[now]] + 1);
now = fa[top[now]];
}
return seg[id[now] - k];
}
int main()
{
cin >> n >> m >> S;
for (int i = 1; i <= n; i++)
{
int u;
cin >> u;
if (!u)
root = i;
else
add(u, i);
}
dfs1(root, 0);
dfs2(root, root);
for (int i = 1; i <= m; i++)
{
long long u = (get(S) ^ lastans) % n + 1, k = (get(S) ^ lastans) % deep[u];
lastans = query(u, k);
ans ^= 1ll * i * lastans;
}
cout << ans;
return 0;
}