长剖求调0pts全部RE
查看原帖
长剖求调0pts全部RE
929151
xxr___楼主2025/8/4 14:08
#include <iostream>
#include <vector>
#include <functional>
constexpr int N = 5e5 + 5;
std::vector<int> e[N];
int cnt = 0,id[N],leaf[N],dep[N],f[N][20],top[N],son[N],lg[N];
std::vector<int> up[N],dn[N];
/*
dn[i] 第 i 个长链从链头到链尾
up[i] 第 i 个长链从链头的父亲一直往上第 i 个链的长度分别是哪些点,从下向上记录 
*/
int main(){
//	std::ios::sync_with_stdio(false);
//	std::cin.tie(nullptr);	
	int n,q,root = 0;
	unsigned int s;
	std::cin >> n >> q >> s;
	for(int i = 1,x; i <= n; ++ i){
		std::cin >> x;
		if(x) e[x].push_back(i);
		else root = i;
		if(i > 1){
			lg[i] = lg[i >> 1] + 1;
		}
	}
	std::function<void(int,int)> dfs;
	leaf[0] = -1;
	dfs = [&](int x,int fa) -> void{
		dep[x] = dep[fa] + 1;
		f[x][0] = fa;
		for(auto & v : e[x]){
			dfs(v,x);
			leaf[x] = std::max(leaf[x],leaf[v] + 1);
			if(leaf[v] > leaf[son[x]]){
				son[x] = v;
			} 
		}
		for(int j = 1; j <= 19; ++ j){
			f[x][j] = f[f[x][j - 1]][j - 1];
		}
	};
	dfs(root,0);
	// leaf[i] 表示 i 所在的长链链尾距离 i 的距离
	std::function<void(int,int)> dfs2;
	dfs2 = [&](int x,int topx) -> void{
		top[x] = topx;
		if(x == topx){
			++ cnt;
			id[x] = cnt;
			int now = f[x][0];
			for(int i = 1; i <= leaf[x] + 1; ++ i){
				up[cnt].push_back(now);
				now = f[now][0];
			}
			now = x;
			for(int i = 1; i <= leaf[x] + 1; ++ i){
				dn[cnt].push_back(now);
				now = son[now];
			}
		}
		if(son[x]) dfs2(son[x],topx);
		for(auto & v : e[x]){
			if(v != son[x]){
				dfs2(v,v);
			}
		}
	};
	dfs2(root,root);
	auto get = [&](unsigned int x) -> unsigned int{
		x ^= x << 13;
		x ^= x >> 17;
		x ^= x << 5;
		return s = x;
	};
	int last_ans = 0,ans = 0;
	auto ask = [&](int i) -> void{
		int x,k;
		x = (get(s) ^ last_ans) % n + 1;
		k = (get(s) ^ last_ans) % dep[x];
		int v = f[x][lg[k]],res = k - (1 << lg[k]);
		res -= dep[v] - dep[top[v]];
//		std::cerr << x << ' ' << k << '\n'; 
		v = top[v];
		if(!res){
			last_ans = v;
		}
		if(res < 0){
//			std::cout << i << ' ' << lg[k] << ' ' << f[x][lg[k]] << '\n'; 
//			std::cerr << v << ' ' << id[v] << '\n';
//			std::cerr << -res << ' ' << dn[id[v]].size() << '\n';
			last_ans = dn[id[v]][-res];
		}
		if(res > 0){
			last_ans = up[id[v]][res - 1];
		}
//		std::cout << last_ans << '\n';
		ans ^= i * last_ans;
	};
//	std::cout << 
//	for(int i = 1; i <= n; ++ i){
//		std::cerr << i << "top : " << top[i] << '\n';
//	}
	for(int i = 1; i <= q; ++ i) ask(i);
	std::cout << ans;
	return 0;
}
2025/8/4 14:08
加载中...