题目
Examples
input
4
BAAAAAAAABBABAB
output
16
input
2
BAA
output
1
input
2
ABA
output
2
input
2
AAB
output
2
input
2
AAA
output
1
大致翻译:
给出一个n层一个完全二叉树以及它的前序遍历的结点上对应的字母,结点只能为A或B,现在可以任意翻转节点上的左右子树,形成一个新的前序遍历字符串,问字符串有多少种不同的情况。
思路:
将每个节点的左右子树构成的字符串按左小右大的顺序放置,这样可以排除AB\BA对结果的影响,
若此时结点的左右子树不同,说明左右交换可以改变字符串的顺序,统计不同情况的数目(设为y),答案即2y(每交换一次可以得到两种不同的字符串);
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+10;
const int inf=0x3f3f3f3f;
const int mod=998244353;
int n;
string s;
int ans=1;
string dfs(int x){
if(x<(1<<(n-1))){//非叶子节点
string l=dfs(x<<1);
string r=dfs(x<<1|1);
if(l!=r){
ans=(ans*2)%mod;
}
if(l>r)swap(l,r);
return s[x]+l+r;
}else{//叶子节点,直接返回
if(s[x]=='A')return "A";
else return "B";
}
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>s;
s=" "+s;
dfs(1);
cout<<ans<<endl;
return 0;
}