求助长链剖分,奇奇怪怪的RE
查看原帖
求助长链剖分,奇奇怪怪的RE
92682
Eric_cai楼主2022/7/20 19:20
#include<iostream>
#include<cstdio>
#include<vector>
#include<cassert>
#define maxn 500005
#define ui unsigned int
#define ll long long
using namespace std;
ui s;
inline ui get(ui x) {
    x ^= x << 13;
    x ^= x >> 17;
    x ^= x << 5;
    return s = x; 
} 
ll n,q,rt,p[maxn],fa[maxn][23],tp[maxn],dist[maxn];
ll dep[maxn],ls[maxn],Max[maxn],val[maxn],len[maxn];
vector<ll> son[maxn],down[maxn],up[maxn];
void dfs(int now)
{
	for(int i=1;i<=20;i++) fa[now][i]=fa[fa[now][i-1]][i-1];
	dep[now]=dep[fa[now][0]]+1;
	Max[now]=dep[now];
	for(int i=0;i<son[now].size();i++)
	{
		dfs(son[now][i]);
		if(Max[now]<Max[son[now][i]]) ls[now]=son[now][i];
		Max[now]=max(Max[now],Max[son[now][i]]);
	}
}
void dfs1(int now,int Top)
{
	down[Top].push_back(now);
	tp[now]=Top;
	if(now!=Top) dist[now]=dist[fa[now][0]]+1;
	if(ls[now]!=0) dfs1(ls[now],Top);
	for(int i=0;i<son[now].size();i++)
		if(son[now][i]!=ls[now]) dfs1(son[now][i],son[now][i]);
	if(now==Top)
	{
		len[now]=down[now].size()+5;
		int zu=fa[now][0];
		for(int i=1;i<=len[now];i++)
		{
			up[i].push_back(zu);
			zu=fa[zu][0];
		}
	}
}
int get_ans(int x,int k)
{
	if(k==0) return x;
	x=fa[x][p[k]];
	k-=val[k];
	k-=dist[x];
	x=tp[x];
	if(k-1>=0) return up[x][k-1];
	if(k<=0) return down[x][-k];
}
signed main()
{
	scanf("%lld%lld",&n,&q);
	cin>>s;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&fa[i][0]);
		if(fa[i][0]==0) rt=i;
		son[fa[i][0]].push_back(i);
	}
	dfs(rt);
	dfs1(rt,rt);
	p[1]=0;
	val[1]=1;
	int now=1;
	for(int i=2;i<=n;i++)
	{
		if(p[i]==2*now)
		{
			p[i]=p[i-1]+1;
			val[i]=val[i-1]*2;
		}
		else
		{
			p[i]=p[i-1];
			val[i]=val[i-1];
		}
	}
	ll x,k,ans=0,sum=0;
	for(int i=1;i<=q;i++)
	{
		x=(get(s)^ans)%n+1;
		k=(get(s)^ans)%dep[x];
		ans=get_ans(x,k);
		sum^=i*ans;
	}
	printf("%lld\n",sum);
	return 0;
}
2022/7/20 19:20
加载中...