1 条题解
-
0
洛谷上写过的,懒得再写一遍暴力做法很简单, 判断两棵树是否相等,可惜要 TLE。
判断两个子字符串是否相等时,我们用一个哈希值代替字符串进行比较,判断两个子树相等也是如此。
设 为哈希函数, 也是一个哈希函数,则一棵树以节点 为根节点的子树不交换左右节点的哈希值为:
其中, 为以 节点为根节点的哈希值, 表示 的左儿子的编号, 表示 的右儿子的编号, 表示第 个点的权值。
交换左右节点的哈希值为:
因此,我们可以求出每个子树交换和不交换左右儿子的哈希值。
如果这两个哈希值相等,则这个子树是对称二叉树。
这样,这道题就可做了。遍历每个子树,如其交换左右节点的哈希值与不交换左右节点的哈希值相等,则把当前子树的节点个数与当前最大对称二叉子树的节点数比较,进行更新即可。
#include<bits/stdc++.h> using namespace std; int n; int a[1000005],l[1000005],r[1000005]; long long h1[1000005],h2[1000005],sz[1000005]; constexpr long long p1=100003,q1=100043; constexpr long long p2=4000037,q2=4000079; constexpr long long mod1=100000000003,mod2=100000000019; long long ans=0; long long hc1(long long x) { x^=x>>4; return x*p2; } long long hc2(long long x) { x^=x<<2; return x*q2; } void init(int id) { if(id==0) { return ; } init(l[id]); init(r[id]); h1[id]=h2[id]=a[id]; sz[id]=1; h1[id]+=hc1(h1[l[id]])+hc2(h1[r[id]]); h1[id]%=mod1; h2[id]+=hc2(h2[l[id]])+hc1(h2[r[id]]); h2[id]%=mod1; sz[id]+=sz[l[id]]+sz[r[id]]; if(h1[l[id]]!=h2[r[id]]||sz[l[id]]!=sz[r[id]]) { return ; } ans=max(ans,sz[id]); } int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } for(int i=1;i<=n;i++) { cin>>l[i]>>r[i]; l[i]=max(l[i],0); r[i]=max(r[i],0); } init(1); cout<<ans; }
信息
- ID
- 440
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 33
- 已通过
- 14
- 上传者