栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Educational Codeforces Round 127 (Rated for Div. 2) E. Preorder (树形dp)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Educational Codeforces Round 127 (Rated for Div. 2) E. Preorder (树形dp)

Educational Codeforces Round 127 (Rated for Div. 2) E. Preorder (树形dp) E. Preorder

题意: 给定一课完全二叉树(确定),每个结点的值是字符’A’或’B’中的一个,你可以进行以下操作若干次:

  • 选定一个结点 u,对于左孩子 u<<1 和右孩子 u<<1|1,将 u 的左孩子置为 u<<1|1 ,右孩子置为 u<<1(可以认为是交换了两棵子树,这有可能会影响遍历顺序)

随后先序遍历这课树,得到先序遍历后的结果string end,问end有多少种不同的结果

分析: 首先什么情况下交换某根结点下的两颗子树其结果和不交换是相同的。答案是两颗子树本质是相同的,那么总方案数为 d p l dp_l dpl​ * d p r dp_r dpr​。如果两颗子树本质不相同,那么交换之后会产生额外的方案即: d p l dp_l dpl​ * d p r dp_r dpr​,即总方案数为 2 2 2 * d p l dp_l dpl​ * d p r dp_r dpr​。

那么我们该如何判断两颗子树本质相不相同呢?: 本题可以采取暴力做法,时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),即以某根为结点暴力搜索其子树,判断左子树和右子树构造的string是否相等,来判断左右子树是否本质上是相同的。构造方案:两个子树合并的时候字典序小的string放前面,这样构造在目标根的时候左右子树的string,必然都是其字典序最小情况,直接判断即可。

code:

#include
using namespace std;
#define int long long
const int N = 3e5+10;
const int mod = 998244353;
int tot;
char s[N];
int sum[N];
string dfs(int u){
    if((u<<1|1)>=tot){
        if(s[u]=='A')return "A";
        else return "B";
    }
    string left=dfs(u<<1);
    string right=dfs(u<<1|1);
    if(left==right){
        sum[u]=(sum[u<<1]*sum[u<<1|1])%mod;
    }
    else{
        sum[u]=(2*(sum[u<<1]*sum[u<<1|1]))%mod;
    }
    if(left>right)swap(left,right);
    return left+s[u]+right;
}
signed main(){
    int n;
    cin>>n;
    scanf("%s",s+1);
    tot=1<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/832577.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号