列表

详情


NC213882. CCA的树

描述

创造是人的天性,更进一步地说,创造是人的意义。
你想创造一棵树,于是你找来了 n 个结点,把它们拼接在了一起 。
你觉得这棵树太单调了,于是又找来 m 种颜料,用其中的一些给这棵树染色。
你认为一个染色的方案是美的,当且仅当树上存在一条好看的链,好看的链满足以下条件:
1、链的两端结点颜色相同 。
2、链上存在一个端点以外的结点,它的颜色与端点不同 。
许久之后,你已经忘记当时是如何拼接的,又是如何染色的,仅仅记得当时找来了多少结点和多少种颜料。
你想计算出染色方案数的期望,以此追忆当年的创造 。
PS:对于一颗已经确定的树,其染色方案数是确定的,但是一颗 n 个结点的树有很多种形态,染色方案数的期望即为 (所有形态染色方案数之和)/ (形态数)。

输入描述

一行,两个整数 n , m

输出描述

一行,一个整数表示染色方案数的期望对 1023694381 取模后的值 。

示例1

输入:

4 2

输出:

8

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 254ms, 内存消耗: 156792K, 提交时间: 2020-12-21 00:03:38

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
typedef long long ll;
const int N=1e7+4;
const ll M=1023694381ll;
using namespace std;
ll n,m,s[N],inv[N];
ll pm(ll x,ll b){x%=M;ll res=1;while(b){if(b&1)res=res*x%M;b>>=1;x=x*x%M;}return res;}
ll C(ll n,ll m){return s[n]*inv[m]%M*inv[n-m]%M;}
void f1(){
	scanf("%lld%lld",&n,&m);
	s[0]=1;
	int nn=max(n,m);
	for(int i=1;i<=nn;i++)s[i]=s[i-1]*i%M;
	inv[nn]=pm(s[nn],M-2);inv[0]=1;
	for(int i=nn-1;i>=1;i--)inv[i]=inv[i+1]*(i+1)%M; 
	ll ans=pm(m,n);
	for(ll i=0;i<=n-1;i++){
		if(i+1<=m)ans=(ans-C(m,i+1)*C(n-1,i)%M*s[i+1]%M+M)%M;
	}
	printf("%lld",ans);
}

int main(){
	f1(); 
	return 0;
} 

上一题