[CF1528E]Mashtali and Hagh Trees
Posted Tan_tan_tann
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1528E]Mashtali and Hagh Trees相关的知识,希望对你有一定的参考价值。
Mashtali and Hagh Trees
题解
由于我们求出的树要求是不同构的树,我们不妨先给每个树假定一个根,该根满足下面的条件。
- 它有 0 / 2 0/2 0/2入边,且其它节点的所有出边都与该节点的父边方向相同。
容易发现,所有符合条件的树的根都满足该条件,否则一定可以通过向出边走找到一个符合条件的点做根。
而如果一棵树不止一个点拥有
⩾
2
\\geqslant2
⩾2条入边,那么我们一定可以找到不满足条件
3
3
3的一对点。
所以任意一棵树我们都可以这样找到这样的唯一一个根,于是我们也就可以将我们的树从这里开始分成
3
3
3类。
- 所有的边都指向根节点。
- 所有的边都指向根节点的反方向。
- 2 2 2棵根节点儿子的子树的所有节点指向根节点, 1 1 1棵指向根节点的反方向且该棵子树非链。
前面两类其实是可以合并在一起考虑的,第二类相当于将第一类的所有边翻转一下。
而由于每个节点的度数不能超过
3
3
3,所以每个非根节点的儿子数不能超过
2
2
2。
我们定义
f
i
f_{i}
fi表示深度为
i
i
i的满足条件的二叉树个数,并定义
p
r
e
i
pre_{i}
prei表示
f
f
f数组的前缀和。容易得到
d
p
dp
dp转移式:
f
i
=
f
i
−
1
+
f
i
−
1
p
r
e
i
−
2
+
f
i
−
1
(
f
i
−
1
+
1
)
2
f_{i}=f_{i-1}+f_{i-1}pre_{i-2}+\\frac{f_{i-1}(f_{i-1}+1)}{2}
fi=fi−1+fi−1prei−2+2fi−1(fi−1+1)
相当于枚举根节点的
1
/
2
1/2
1/2个儿子子树的情况,至少要有一个子树深度为
i
−
1
i-1
i−1,其它儿子深度不超过
i
−
1
i-1
i−1。最后一个
f
i
−
1
(
f
i
−
1
+
1
)
2
\\frac{f_{i-1}(f_{i-1}+1)}{2}
2fi−1(fi−1+1)是为了排除两个子树深度同样为
i
i
i的树时两个子树同构与两个子树被重复枚举的情况。
再定义
g
i
g_{i}
gi表示深度为
i
i
i的满足条件的根的度数为
2
2
2的二叉树个数,很明显
g
i
=
f
i
−
f
i
−
1
g_{i}=f_{i}-f_{i-1}
gi=fi−fi−1。
那么前两种的答案为:
A
n
s
1
=
2
(
f
n
+
f
n
−
1
(
f
n
−
1
+
1
)
p
r
e
i
−
2
2
+
f
n
−
1
p
r
e
i
−
2
(
p
r
e
i
−
2
+
1
)
2
+
f
n
−
1
(
f
n
−
1
+
1
)
(
f
n
−
1
+
2
)
6
)
−
1
Ans1=2(f_{n}+\\frac{f_{n-1}(f_{n-1}+1)pre_{i-2}}{2}+\\frac{f_{n-1}pre_{i-2}(pre_{i-2}+1)}{2}+\\frac{f_{n-1}(f_{n-1}+1)(f_{n-1}+2)}{6})-1
Ans1=2(fn+2fn−1(fn−1+1)prei−2+2fn−1prei−2(prei−2+1)+6fn−1(fn−1+1)(fn−1+2))−1
相当于先前已经算好的根节点只有
1
/
2
1/2
1/2个儿子的情况加上枚举根的
3
3
3个儿子子树的状况,同样至少有一个儿子深度要达到
n
−
1
n-1
n−1,其它儿子深度不超过
n
−
1
n-1
n−1。同样需要考虑重复枚举与同构的情况。
两倍是为了计算边的方向不同的情况,
−
1
-1
−1是因为方向不同的单链也是同构的,需要去掉。
而对于第
3
3
3种情况,要将两个儿子的深度与另一个加在一起考虑,相当于在对于一个有两个儿子的树再增加一棵子树,答案为:
A
n
s
2
=
∑
i
=
0
n
−
1
(
f
i
−
1
)
g
n
−
i
−
1
Ans2=\\sum_{i=0}^{n-1}(f_{i}-1)g_{n-i-1}
Ans2=i=0∑n−1(fi−1)gn−i−1
f
i
−
1
f_{i}-1
fi−1是为了去掉出边的那一个儿子是单链的情况。
答案将
A
n
s
1
Ans1
Ans1与
A
n
s
2
Ans2
Ans2加在一起就可以得到了。
时间复杂度 O ( n ) O\\left(n\\right) O(n),也就一个简单的 d p dp dp转移。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000005
#define lowbit(x) (x&-x)
#define reg register
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const LL INF=0x7f7f7f7f7f7f7f7f;
const int mo=998244353;
const int zero=500;
const LL jzm=2333;
const int inv2=499122177;
const int inv6=166374059;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)prin以上是关于[CF1528E]Mashtali and Hagh Trees的主要内容,如果未能解决你的问题,请参考以下文章