64分WA大测试点,求大佬debug,特意加了注释(确信
查看原帖
64分WA大测试点,求大佬debug,特意加了注释(确信
280233
Lee666666楼主2021/10/4 16:55

题目传送门

#include <bits/stdc++.h>
using namespace std;

typedef unsigned long long ULL;

const int maxn = 1000015;
const ULL mod = 1009; // 哈希の取模 

inline int read() { // 快读 
	int s = 0, f = 1;
	char ch = getchar();
	while (ch < 48 || ch > 57) {
		if (ch == 45) {
			f = -1;
		}
		ch = getchar();
	}
	while (ch > 47 && ch < 58) {
		s = (s << 3) + (s << 1) + ch - 48;
		ch = getchar();
	}
	return s * f;
}

int n, ans, v[maxn], sz[maxn], child[maxn][2]; // sz[u]维护u及其子树的大小 
ULL h[maxn][2], mod_pow[maxn]; // h[u][0]与h[u][1]分别维护u及其子树哈希值的正序和逆序,mod_pow[i]维护mod的i次幂(取模) 

void dfs(int u) {
	if (child[u][0] == -1 && child[u][1] == -1) { // 当u是叶子结点 
		h[u][0] = h[u][1] = v[u];
		ans = max(ans, sz[u] = 1); // 更新ans 
	}
	else if (child[u][0] == -1 && child[u][1] > 0) { // 当u只有左子树或右子树 
		dfs(child[u][1]);
		sz[u] = sz[child[u][1]] + 1;
		h[u][0] = v[u] * mod_pow[sz[child[u][1]]] + h[child[u][1]][0];
		h[u][1] = h[child[u][1]][1] * mod + v[u];
	}
	else if (child[u][0] > 0 && child[u][1] == -1) {
		dfs(child[u][0]);
		sz[u] = sz[child[u][0]] + 1;
		h[u][0] = h[child[u][0]][0] * mod + v[u];
		h[u][1] = v[u] * mod_pow[sz[child[u][0]]] + h[child[u][0]][1];
	}
	else { // 当u同时有左子树和右子树 
		dfs(child[u][0]);
		dfs(child[u][1]);
		sz[u] = sz[child[u][0]] + sz[child[u][1]] + 1;
		h[u][0] = h[child[u][0]][0] * mod_pow[sz[child[u][1]] + 1] + mod_pow[sz[child[u][1]]] * v[u] + h[child[u][1]][0];
		h[u][1] = h[child[u][1]][1] * mod_pow[sz[child[u][0]] + 1] + mod_pow[sz[child[u][0]]] * v[u] + h[child[u][0]][1];
		if (h[child[u][0]][0] == h[child[u][1]][1]) { // 更新ans 
			ans = max(ans, sz[u]);
		}
	}
	return;
}

int main(void) {
	mod_pow[0] = 1;
	n = read();
	for (register int i = 1; i <= n; i++) {
		v[i] = read();
		mod_pow[i] = mod_pow[i - 1] * mod; // 取模预处理 
	}
	for (register int i = 1; i <= n; i++) {
		child[i][0] = read();
		child[i][1] = read();
	}
	dfs(1);
	printf("%d", ans);
	return 0;
} 
2021/10/4 16:55
加载中...