E. Preorder(树哈希)

传送门

题意

在这里插入图片描述

思路

我对哈希一无所知,因此直接贴大佬的题解。
在这里插入图片描述
在这里插入图片描述
所以问题主要在于如何确定两颗树是否本质不同

这里使用树哈希,哈希函数如下;

在这里插入图片描述

当前节点的值为A,那么就取 P 0 P_0 P0;为B,则取 P 1 P_1 P1

其中 P 0 , P 1 P_0,P_1 P0,P1为两个大的素数,depth为深度;

这样的哈希函数保证了,本质相同的两棵子树,其哈希值一定也相同。不过严格来说,哈希值相同并不能反过来推定两棵子树是本质相同的,所以该方法还是有可能出错的。

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = (1<<19) + 10;
const int MOD = 998244353;
char str[N];
int n;
ll f[N];
ll h[N];//树哈希
int qpow(int x,int y){
    ll ret = 1,base = x;
    while(y){
        if(y&1) ret = ret * base % MOD;
        base = base * base % MOD;
        y >>= 1;
    }
    return ret % MOD;
}
const int p0 = 1015159,p1 = 1e9+7;
void dfs(int u,int dep){
    if(u*2 > (1<<n)-1){//叶子节点
        f[u] = 1;
        int p = str[u] == 'A'?p0:p1;
        h[u] = qpow(p,dep);
        return;
    }
    int lc = u << 1;
    int rc = u << 1 | 1;
    dfs(lc,dep+1);
    dfs(rc,dep+1);
    int p = str[u] == 'A'?p0:p1;
    h[u] = ((h[lc]*h[rc])%MOD+qpow(p,dep))%MOD;
    f[u] = (f[lc]*f[rc])%MOD;
    //如果左右树不同,再*个2
    if(h[lc] != h[rc]) f[u] = (2*f[u])%MOD;
}
void solve(){
    cin >> n;
    cin >> (str+1);
    dfs(1,1);
    cout << f[1] << '\n';
}
signed main(){
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    solve();
    return 0;
}

参考资料

题解1
题解2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值