分析
赛时已经想到了子树*2的方法,但是没想到怎么去掉重复的东西,实际上已经很接近答案了。
在子树本质相同的时候,通过交换是没法*2的,所以就记录字典序,比较最小字典序是否相同,这个可以用DFS实现。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int mod=998244353;
int n,a[1000010],p;
string s[1000010];
ll f[1000010];
void dfs(int x)
{
int ls=x*2,rs=x*2+1;
if(ls>p) //叶子
{
s[x]=a[x]+'0';
f[x]=1;
return;
}
dfs(ls);dfs(rs);
if(s[ls]==s[rs]) f[x]=f[ls]*f[rs]%mod;
else f[x]=f[ls]*f[rs]%mod*2%mod;
s[x]=a[x]+'0';
if(s[ls]<s[rs]) s[x]=s[x]+s[ls]+s[rs];//判字典序
else s[x]=s[x]+s[rs]+s[ls];
}
int main()
{
cin>>n;
p=pow(2,n)-1;
for(int i=1;i<=p;i++)
{
char c;
cin>>c;
if(c=='A') a[i]=1;
}
dfs(1);
cout<<f[1];
return 0;
}