• CF1528E Mashtali and Hagh Trees 题解


    Codeforces
    Luogu

    P.S.

    上文

    Solution.

    观察三条件,抽象出树可能是以下三种

    1. 有根外向树
    2. 有根内向树
    3. 内向外向拼起来

    设有根且根度数为 \(2\) 的方案数是 \(\{F_i\}\)

    1. 根度为 \(1\),为 \(F_{n-1}\)
    2. 根的点度为 \(2\),且左右深度不相同,为 \(F_{n-1}\times\left(\sum_{i=0}^{n-2}F_i\right)\)
    3. 根的点度为 \(2\),且左右深度相同,为 \(\cfrac{F_{n-1}\times(F_{n-1}+1)}{2}\)

    \[\therefore \begin{aligned} F_n&=F_{n-1}+F_{n-1}\times\left(\sum_{i=0}^{n-2}F_i\right)+\cfrac{F_{n-1}\times(F_{n-1}+1)}{2}\\ &=F_{n-1}+F_{n-1}\times\left(\sum_{i=0}^{n-2}F_i\right)+\dbinom {F_{n-1}+1}2 \end{aligned} \]

    所以我们可以在 \(O(n)\) 的复杂度内求出 \(\{F_i\}\)

    统计答案,发现 12 都分别有下式种方案。

    \[F_n+F_{n-1}\times\dbinom{1+\sum_{i=0}^{n-2}F_i}2+\left(\sum_{i=0}^{n-2}F_{i}\right)\times\dbinom{F_{n-1}+1}2+\dbinom{F_{n-1}+2}3 \]

    但是我们需要注意的是一条链的情况 12 会算重,所以两倍后要减 \(1\)

    与此同时,第三种情况的计算比较复杂。
    首先左边的有根内向树是 \(F_i-1\),因为不能退化成链。
    右边的是 \(F_{n-i-1}-F_{n-i-2}\),因为根度不能为一。
    所以答案是 \(\sum_{i=0}^{n-1}(F_i-1)\times(F_{n-i-1}-F_{n-i-2})\)

    最后答案加一下就好了。

    Coding.

    点击展开代码
    //是啊……你就是那只鬼了……所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }/*}}}*/
    const int P=998244353;int n,F[1000005],s[1000005];
    inline int ksm(int x,int q=P-2) {int r=1;for(;q;q>>=1,x=1ll*x*x%P) if(q&1) r=1ll*r*x%P;return r;}
    inline int C2(int x) {return 1ll*x*(x+1)%P*499122177%P;}
    inline int C3(int x) {return 1ll*x*(x+1)%P*(x+2)%P*166374059%P;}
    int main()
    {
    	read(n),F[0]=1,F[1]=2,s[0]=1,s[1]=3;int rs=0;
    	if(n==1) return puts("5"),0;else if(n==2) return puts("31"),0;
    	for(int i=2;i<=n;i++) F[i]=(F[i-1]+1ll*F[i-1]*s[i-2]+C2(F[i-1]))%P,s[i]=(s[i-1]+F[i])%P;
    	rs=(2ll*F[n]-1+2ll*C3(F[n-1])+2ll*F[n-1]*C2(s[n-2])+2ll*s[n-2]*C2(F[n-1]))%P;
    	for(int i=0;i<n-1;i++) rs=(rs+1ll*(F[i]-1)*(F[n-i-1]-F[n-i-2]))%P;
    	return printf("%d\n",rs),0;
    }
    
  • 相关阅读:
    vim+makefile入门编辑,编译,差错实例
    vim操作备忘录
    vim学习、各类插件配置与安装
    ubuntu命令行下java工程编辑与算法(第四版)环境配置
    【RabbitMQ】命令行使用学习
    【Docker】RabbitMQ使用学习
    Jmeter如何把响应数据的结果保存到本地的一个文件
    Selenium + Python 自动化测试环境搭建
    Jmeter监控服务器-CPU,Memory,Disk,Network性能指标
    Jmeter 聚合报告---测试结果分析
  • 原文地址:https://www.cnblogs.com/pealfrog/p/14985675.html
Copyright © 2020-2023  润新知