P5018 [NOIP2018 普及组] 对称二叉树


P5018 [NOIP2018 普及组] 对称二叉树

题目

P5018

思路

通过hash值来判断左右树是否相等

\(hl[i]\)\(Hl[i]\) 是防止hash冲突, \(r\) 同理

注意,在 \(hl,hr\) 计算的时候大质数的顺序

\(hash\) 过程中会出现非常大的数字

常见的孪生质数: \(1e9+7,1e9+9\)

问题

此题为什么不能使用自然溢出解决?

CPP

#include 
//#define int long long
#define int unsigned long long
const int p1=999999751;
const int p2=100000007;
const int p3=299999827;
const int mod1=89999794200117649;
const int mod2=999999786000011449;
const int N=1e6+10;
using namespace std;
int v[N],node[N];
int Hl[N],hl[N],Hr[N],hr[N];
int n,ans;

struct qwq {
	int l,r;
} tree[N];

inline int read() {
	int x, f = 1;
	char c;
	while (!((c = getchar()) >= '0' && c <= '9')) if (c == '-') f = -1;
	x = c - '0';
	while ((c = getchar()) >= '0' && c <= '9') (x *= 10) += c - '0';
	return x * f;
}

inline void write(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 ^ 48);
}

inline void dfs(int x) {
	if(tree[x].l) dfs(tree[x].l);
	if(tree[x].r) dfs(tree[x].r);
	node[x]=node[tree[x].l]+node[tree[x].r]+1;
	if(node[tree[x].l]==node[tree[x].r] && hl[tree[x].l]==hr[tree[x].r] && Hl[tree[x].l]==Hr[tree[x].r])
		ans=max(ans,node[x]);
	hl[x]=(hl[tree[x].l]*p1+hl[tree[x].r]*p2+v[x]*p3)%mod1;
	Hl[x]=(Hl[tree[x].l]*p1+Hl[tree[x].r]*p2+v[x]*p3)%mod2;
	hr[x]=(hr[tree[x].l]*p2+hr[tree[x].r]*p1+v[x]*p3)%mod1;
	Hr[x]=(Hr[tree[x].l]*p2+Hr[tree[x].r]*p1+v[x]*p3)%mod2;
}

signed main() {
	n=read();
	for(int i=1; i<=n; i++)
		v[i]=read();
	for(int i=1; i<=n; i++) {
		int l=read(),r=read();
		if(l!=-1) tree[i].l=l;
		if(r!=-1) tree[i].r=r;
	}
	dfs(1);
	write(ans);putchar('\n');
	return 0;
}