博客
关于我
[bzoj5093][第二类斯特林数][NTT]图的价值
阅读量:85 次
发布时间:2019-02-26

本文共 3389 字,大约阅读时间需要 11 分钟。

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

题解

一般都要单独考虑一个点的贡献
显然这个点的贡献是独立的,最后乘一个n就可以
那单独一个点的贡献就是
∑ i = 1 n − 1 C n − 1 i ∗ 2 ( n − 1 ) ( n − 2 ) 2 ∗ i k \sum_{i=1}^{n-1}C_{n-1}^i*2^{\frac{(n-1)(n-2)}{2}}*i^k i=1n1Cn1i22(n1)(n2)ik
2的次幂是常数,提到前面去,把n减一,显然我们只需要算
∑ i = 1 n C n i ∗ i k \sum_{i=1}^nC_{n}^{i}*i^k i=1nCniik
根据第二类斯特林数的性质,我们可以知道
∑ i = 1 n C n i ∑ j = 0 m i n ( i , k ) S ( k , j ) ∗ j ! ∗ C i j \sum_{i=1}^nC_{n}^{i}\sum_{j=0}^{min(i,k)}S(k,j)*j!*C_{i}^{j} i=1nCnij=0min(i,k)S(k,j)j!Cij
乘法分配律一下,显然可以把斯特林数提前
∑ i = 0 m i n ( n , k ) S ( k , i ) ∗ i ! ∗ ∑ j = i n C n j ∗ C j i \sum_{i=0}^{min(n,k)}S(k,i)*i!*\sum_{j=i}^{n}C_n^j*C_{j}^{i} i=0min(n,k)S(k,i)i!j=inCnjCji
后面的式子的意义就是在n中选i个数,其它可选可不选,所以就是
∑ i = 0 m i n ( n , k ) S ( k , i ) ∗ i ! ∗ C n i ∗ 2 n − i \sum_{i=0}^{min(n,k)}S(k,i)*i!*C_{n}^{i}*2^{n-i} i=0min(n,k)S(k,i)i!Cni2ni
现在就是要算前面的斯特林数了
可以容斥然后NTT n l o g n nlogn nlogn求,点一下就知道啦

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<queue>#include<vector>#include<ctime>#include<map>#include<bitset>#define LL long long#define mp(x,y) make_pair(x,y)#define pll pair<long long,long long>#define pii pair<int,int>using namespace std;inline LL read(){   	LL f=1,x=0;char ch=getchar();	while(ch<'0'||ch>'9'){   if(ch=='-')f=-1;ch=getchar();}	while(ch>='0'&&ch<='9'){   x=x*10+ch-'0';ch=getchar();}	return x*f;}int stack[20];inline void write(int x){   	if(x<0){   putchar('-');x=-x;}    if(!x){   putchar('0');return;}    int top=0;    while(x)stack[++top]=x%10,x/=10;    while(top)putchar(stack[top--]+'0');}inline void pr1(int x){   write(x);putchar(' ');}inline void pr2(int x){   write(x);putchar('\n');}const LL mod=998244353;const int MAXN=200005;LL pow_mod(LL a,LL b){   	LL ret=1;	while(b)	{   		if(b&1)ret=ret*a%mod;		a=a*a%mod;b>>=1;	}	return ret;}LL A[MAXN*4],B[MAXN*4];int R[MAXN*4],L;void NTT(LL *y,int len,int on){   	for(int i=0;i<len;i++)if(i<R[i])swap(y[i],y[R[i]]);	for(int i=1;i<len;i<<=1)	{   		LL wn=pow_mod(3,(mod-1)/(i*2));if(on==-1)wn=pow_mod(wn,mod-2);		for(int j=0;j<len;j+=(i<<1))		{   			LL w=1;			for(int k=0;k<i;k++)			{   				LL u=y[j+k];				LL v=y[j+k+i]*w%mod;				y[j+k]=(u+v)%mod;				y[j+k+i]=(u-v+mod)%mod;				w=w*wn%mod;			}		}	}	if(on==-1)	{   		LL temp=pow_mod(len,mod-2);		for(int i=0;i<len;i++)y[i]=y[i]*temp%mod;	}}int n,K;LL pre[MAXN],inv[MAXN];LL C[MAXN];void init(){   	C[0]=1;LL temp=1;	for(int i=1;i<=min(n,K);i++)	{   		temp=temp*(n-i+1)%mod;		temp=temp*pow_mod(i,mod-2)%mod;		C[i]=temp;	}}int main(){   	pre[0]=1;for(int i=1;i<=MAXN-5;i++)pre[i]=pre[i-1]*i%mod;	inv[MAXN-5]=pow_mod(pre[MAXN-5],mod-2);	for(int i=MAXN-6;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;	n=read();K=read();n--;	init();	int ln;	for(ln=1;ln<=2*K;ln<<=1)L++;	for(int i=0;i<ln;i++)R[i]=(R[i>>1]>>1)|(i&1)<<(L-1);	int temp=-1;	for(int i=0;i<=K;i++)	{   		temp*=-1;		A[i]=temp*inv[i]%mod;		LL u1=pow_mod(i,K),u2=inv[i];		B[i]=u1*u2%mod;	}	NTT(A,ln,1);NTT(B,ln,1);	for(int i=0;i<ln;i++)A[i]=A[i]*B[i]%mod;	NTT(A,ln,-1);	LL ans=0;	for(int i=0;i<=min(n,K);i++)	{   		LL re=A[i]*pre[i]%mod*C[i]%mod*pow_mod(2,n-i)%mod;		ans=(ans+re)%mod;	}	ans=ans*(n+1)%mod*pow_mod(2,(LL)(n)*(n-1)/2)%mod;	pr2(ans);	return 0;}

转载地址:http://immu.baihongyu.com/

你可能感兴趣的文章
msbuild发布web应用程序
查看>>
MSB与LSB
查看>>
MSCRM调用外部JS文件
查看>>
MSCRM调用外部JS文件
查看>>
MSEdgeDriver (Chromium) 不适用于版本 >= 79.0.313 (Canary)
查看>>
MsEdgeTTS开源项目使用教程
查看>>
msf
查看>>
MSSQL数据库查询优化(一)
查看>>
MSSQL数据库迁移到Oracle(二)
查看>>
MSSQL日期格式转换函数(使用CONVERT)
查看>>
MSTP多生成树协议(第二课)
查看>>
MSTP是什么?有哪些专有名词?
查看>>
Mstsc 远程桌面链接 And 网络映射
查看>>
Myeclipse常用快捷键
查看>>
MyEclipse更改项目名web发布名字不改问题
查看>>
MyEclipse用(JDBC)连接SQL出现的问题~
查看>>
mt-datetime-picker type="date" 时间格式 bug
查看>>
myeclipse的新建severlet不见解决方法
查看>>
MyEclipse设置当前行背景颜色、选中单词前景色、背景色
查看>>
Mtab书签导航程序 LinkStore/getIcon SQL注入漏洞复现
查看>>