DESCRIPTION
求有多少个以1号点为根的N个点的带标号有根树, 满足深度为奇数的点恰有K个, 答案对998244353取模
根的深度为1
INPUT
一行两个整数
N,K
OUTPUT
一行一个整数表示答案
SAMPLE INPUT
4 2
SAMPLE OUTPUT
12
HINT
4≤N≤500000,2≤K≤N−1
SOLUTION
D
记SMN 为左边N个点, 右边M个点的完全二分图生成树个数
答案即SKN−K×(N−1K−1), 证明显然, 因为把树上的点按照奇偶分层,即得到一个二分图, 每一棵树都对应了这个完全二分图的一个生成树
SMN=NM−1×MN−1, 暴力用Matrix−Tree可以消元得到这个结论。
第一次听到这个概念 完全二分图生成树,其实你画出来就知道什么是完全二分图生成树了,最后就是找生成树个数 ,公式也给出了,最后再组合替换一下。就是答案了。
总结了一下,做的题太少,看过的知识点太少。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=500000;
ll p[maxn+10];
ll inv[maxn+10];
ll mul(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1)
ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans;
}
void init()
{
p[0]=1;
for(int i=1;i<=maxn;i++)
p[i]=(i*p[i-1])%mod;
for(int i=0;i<=maxn;i++)
inv[i]=mul(p[i],mod-2);
}
ll c(ll nn,ll mm)
{
if(mm>nn)
return 0ll;
if(mm==nn)
return 1ll;
return (((p[nn]*inv[mm])%mod)*inv[nn-mm])%mod;
}
ll lucas(ll nn,ll mm)
{
if(mm==0)
return 1ll;
return c(nn%mod,mm%mod)*lucas(nn/mod,mm/mod)%mod;
}
int main()
{
int n,k;
init();
//printf("%lld\n",lucas(5,2));
while(~scanf("%d%d",&n,&k))
{
ll ans=1;
ans=(ans*mul(k,n-k-1))%mod;
ans=(ans*mul(n-k,k-1))%mod;
//printf("%lld\n",ans);
ans=(ans*lucas(n-1,k-1))%mod;
printf("%lld\n",ans);
}
return 0;
}