Description
“简单无向图”是指无重边、无自环的无向图(不一定连通)。
一个带标号的图的价值定义为每个点度数的k次方的和。
给定n和k,请计算所有n个点的带标号的简单无向图的价值之和。
因为答案很大,请对998244353取模输出。
Input
第一行包含两个正整数n,k(1<=n<=10^9,1<=k<=200000)。
Output
输出一行一个整数,即答案对998244353取模的结果。
Sample Input
6 5
Sample Output
67584000
分析:
式子就不推了。
a
n
s
=
n
∗
2
(
n
−
1
)
(
n
−
2
)
2
∗
∑
i
=
0
n
−
1
S
(
k
,
i
)
∗
i
!
∗
(
n
−
1
i
)
∗
2
n
−
1
−
j
ans=n*2^{\frac{(n-1)(n-2)}{2}}*\sum_{i=0}^{n-1}S(k,i)*i!*\binom{n-1}{i}*2^{n-1-j}
ans=n∗22(n−1)(n−2)∗i=0∑n−1S(k,i)∗i!∗(in−1)∗2n−1−j
显然当
i
>
k
i>k
i>k时,
S
(
k
,
i
)
=
0
S(k,i)=0
S(k,i)=0,所以只要算到
k
k
k。
用ntt算出出第
k
k
k行斯特林数,组合数可以通过计算
n
j
c
[
i
]
=
∏
i
=
n
−
i
+
1
n
i
njc[i]=\prod_{i=n-i+1}^{n}i
njc[i]=∏i=n−i+1ni来计算。
由于
S
(
n
,
m
)
=
1
m
!
∑
k
=
0
m
(
−
1
)
k
(
m
k
)
∗
(
m
−
k
)
n
S(n,m)=\frac{1}{m!}\sum_{k=0}^{m}(-1)^k\binom{m}{k}*(m-k)^n
S(n,m)=m!1k=0∑m(−1)k(km)∗(m−k)n
化成卷积形式就是
S
(
n
,
m
)
=
∑
i
=
0
m
(
−
1
)
k
k
!
∗
(
m
−
k
)
n
(
m
−
k
)
!
S(n,m)=\sum_{i=0}^{m}\frac{(-1)^k}{k!}*\frac{(m-k)^n}{(m-k)!}
S(n,m)=i=0∑mk!(−1)k∗(m−k)!(m−k)n
感觉这个大家都知道了= =
代码:
/**************************************************************
Problem: 5093
User: liangzihao
Language: C++
Result: Accepted
Time:14024 ms
Memory:29416 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cmath>
#define LL long long
const int maxn=2e5+7;
const int maxp=6e5+7;
const LL G=3;
const LL mod=998244353;
using namespace std;
int n,m,len;
LL ans;
LL f[maxp],g[maxp],h[maxp],r[maxp],w[maxp];
LL jc[maxn],njc[maxn],inv[maxn];
LL power(LL x,LL y)
{
if (y==0) return 1;
if (y==1) return x;
LL c=power(x,y/2);
c=(c*c)%mod;
if (y&1) c=(c*x)%mod;
return c;
}
void ntt(LL *a,int f)
{
for (int i=0;i<len;i++)
{
if (i<r[i]) swap(a[i],a[r[i]]);
}
w[0]=1;
for (int i=2;i<=len;i<<=1)
{
LL wn;
if (f==1) wn=power(G,(mod-1)/i);
else wn=power(G,(mod-1)-(mod-1)/i);
for (int j=i/2;j>=0;j-=2) w[j]=w[j/2];
for (int j=1;j<i/2;j++) w[j]=w[j-1]*wn%mod;
for (int j=0;j<len;j+=i)
{
for (int k=0;k<i/2;k++)
{
LL u=a[j+k],v=a[j+k+i/2]*w[k]%mod;
a[j+k]=(u+v)%mod;
a[j+k+i/2]=(u+mod-v)%mod;
}
}
}
if (f==-1)
{
LL inv=power(len,mod-2);
for (int i=0;i<len;i++) a[i]=(a[i]*inv)%mod;
}
}
void NTT(LL *a,LL *b,LL *c,int n,int m)
{
len=1;
int k=0;
while (len<=n+m) len<<=1,k++;
for (int i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(k-1));
ntt(a,1),ntt(b,1);
for (int i=0;i<len;i++) c[i]=(a[i]*b[i])%mod;
ntt(c,-1);
}
int main()
{
scanf("%d%d",&n,&m);
n--;
jc[0]=njc[0]=1;
for (int i=1;i<=m;i++)
{
jc[i]=jc[i-1]*(LL)i%mod;
njc[i]=(njc[i-1]*((LL)n-(LL)i+1))%mod;
}
inv[m]=power(jc[m],mod-2);
for (int i=m;i>0;i--) inv[i-1]=inv[i]*(LL)i%mod;
for (int i=0;i<=m;i++)
{
if (i&1) f[i]=(mod-1)*inv[i]%mod;
else f[i]=inv[i];
g[i]=power(i,m)*inv[i]%mod;
}
NTT(f,g,h,m+1,m+1);
for (int i=0;i<=min(n,m);i++) ans=(ans+h[i]*njc[i]%mod*power(2,(LL)n-i)%mod)%mod;
ans=ans*(LL)(n+1)%mod*power(2,((LL)n*((LL)n-1)/2%(mod-1)))%mod;
printf("%lld\n",ans);
}