1 条题解

  • 0
    @ 2025-3-1 21:20:16

    洛谷上写过的,懒得再写一遍

    暴力做法很简单,O(n)O(n) 判断两棵树是否相等,可惜要 TLE。

    判断两个子字符串是否相等时,我们用一个哈希值代替字符串进行比较,判断两个子树相等也是如此。

    h1(x)h1(x) 为哈希函数,h2(x)h2(x) 也是一个哈希函数,则一棵树以节点 tt 为根节点的子树不交换左右节点的哈希值为:

    h1(hslsont)+h2(hsrsont)+ath1(hs_{lson_t})+h2(hs_{rson_t})+a_t

    其中,hsihs_i 为以 ii 节点为根节点的哈希值,lsonilson_i 表示 ii 的左儿子的编号,rsonirson_i 表示 ii 的右儿子的编号,aia_i 表示第 ii 个点的权值。

    交换左右节点的哈希值为:

    h2(hslsont)+h1(hsrsont)+ath2(hs_{lson_t})+h1(hs_{rson_t})+a_t

    因此,我们可以求出每个子树交换和不交换左右儿子的哈希值。

    如果这两个哈希值相等,则这个子树是对称二叉树。

    这样,这道题就可做了。遍历每个子树,如其交换左右节点的哈希值与不交换左右节点的哈希值相等,则把当前子树的节点个数与当前最大对称二叉子树的节点数比较,进行更新即可。

    #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
    上传者