题意
思路
我对哈希一无所知,因此直接贴大佬的题解。
所以问题主要在于如何确定两颗树是否本质不同;
这里使用树哈希,哈希函数如下;
当前节点的值为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;
}