轻重,,HELP me!
查看原帖
轻重,,HELP me!
291604
王茗仟楼主2022/12/12 11:43
#include<bits/stdc++.h>
#define re register
#define in inline
#define dou long double
using namespace std;
const int N = 1e6 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
//const int mod=9882443535;
const dou eps = 1e-5;
int mod;
in int read() {
	re int x = 0, f = 0; re char c = getchar();
	while (!isdigit(c)) f |= (c == '-'), c = getchar();
	while (isdigit(c))  x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return f ? -x : x;
}
in void write(re int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}

struct edge {
	int u, v;
	int nx;
}e[M << 2];

int tot, head[N];
int res;

in void add(re int u, re int v) {
	e[++tot].u = u;
	e[tot].v = v;
	e[tot].nx = head[u];
	head[u] = tot;
}

int dep[N], fa[N], siz[N], son[N];
int rt;

in void dfs1(re int u, re int f, re int deep) {
	//第一个dfs 算出 fa     dep      size       son
	//每个点的    父节点   深度    子树大小   重儿子
	dep[u] = deep;
	fa[u] = f;
	siz[u] = 1;
	int maxson = -1;
	for (re int i = head[u]; i; i = e[i].nx) {

		re int v = e[i].v;
		if (v == f) continue;//判断回边
		dfs1(v, u, deep + 1);
		siz[u] += siz[v];
		if (siz[v] > maxson) {
			son[u] = v;
			maxson = siz[v];
		}

	}

}

int id[N], wt[N], w[N], top[N], idx;


in void dfs2(re int u, re int topf) {
	/* 找dfs序, 处理每个链找出   ?顶部
	*/
	id[u] = ++idx;
	wt[id[u]] = u;
	top[u] = topf;

	if (!son[u]) return;

	dfs2(son[u], topf);//先走重儿子

	for (re int i = head[u]; i; i = e[i].nx) {
		int v = e[i].v;
		if (v == fa[u] || v == son[u]) continue;

		dfs2(v, v);//走轻边~~
	}
}

int jump(int x, int k) {
	while (k >= id[x] - id[top[x]] + 1 && x != rt) {
		k -= (id[x] - id[top[x]] + 1);
		x = fa[top[x]];
	}
	return wt[id[x] - k];//这个很帅,我靠
}



unsigned int S;

unsigned int get(unsigned int x) {
	x ^= x << 13;
	x ^= x >> 17;
	x ^= x << 5;
	return S = x;
}
int n, m;

signed main() {
	n = read(); m = read();
	cin >> S;

	rt = 1;
	for (int i = 1; i <= n; i++) {
		fa[i] = read();
		if (!fa[i]) {
			rt = i;
		}
		else {
			add(fa[i],i);
		}
	}
	dfs1(rt, 0, 1);
	dfs2(rt, rt);

	long long ans = 0;
	int lastans = 0;
	for (int i = 1; i <= m; i++) {
		int x = (get(S) ^ lastans) % n + 1;
		int k = (get(S) ^ lastans) % dep[x];
		lastans = jump(x, k);
		ans ^=(long long) i * lastans;
	}
	write(ans); putchar(10);
	return 0;
}





树链剖分,对了两个点

2022/12/12 11:43
加载中...