1. 程式人生 > >bzoj 5093: [Lydsy1711月賽]圖的價值

bzoj 5093: [Lydsy1711月賽]圖的價值

價值 a* 得出 bsp www .com k次方 des lin

5093: [Lydsy1711月賽]圖的價值

Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 230 Solved: 123
[Submit][Status][Discuss]

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

HINT

Source

本OJ付費獲取

通過枚舉每個節點的貢獻,我們可以得出: ANS = N * 2^((N-1)*(N-2)/2) * ΣC(N-1,i) * i^K 顯然Σ前面的可以直接提出來,後面的就是某道 codeforces E 題(貌似叫 Team Work)的加強版。 想看接下來的推導的同學可以直接轉到那個題233 (http://www.cnblogs.com/JYYHH/p/8450199.html) 最後推完的式子就是 Σ S(K,i) * P(N,i) * 2^(N-i) ,在那個題裏說了其實K出到10^5級別也是可以做的,用的就是 今天學的斯特林反演,這裏也就不再推了,上一個博客剛剛寫完一個斯特林反演23333。我們直接用NTT就可以求出第K行的所有斯特林數然後帶進去直接算就行了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=660005;
const int ha=998244353;
const int root=3,inv=ha/3+1;
int a[maxn],b[maxn],jc[maxn];
int r[maxn],N,M,n,INV,l,K;

inline int add(int x,int y){
	x+=y;
	return x>=ha?x-ha:x;
}

inline int ksm(int x,int y){
	int an=1;
	for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
	return an;
}

inline void NTT(int *c,const int f){
	for(int i=0;i<N;i++) if(i<r[i]) swap(c[i],c[r[i]]);
	
	for(int i=1;i<N;i<<=1){
		int omega=ksm(f==1?root:inv,(ha-1)/(i<<1));
		for(int p=i<<1,j=0;j<N;j+=p){
			int now=1;
			for(int k=0;k<i;k++,now=now*(ll)omega%ha){
				int x=c[j+k],y=c[j+k+i]*(ll)now%ha;
				c[j+k]=add(x,y);
				c[j+k+i]=add(x,ha-y);
			}
		}
	}
	
	if(f==-1) for(int i=0;i<N;i++) c[i]=c[i]*(ll)INV%ha;
}

inline void init(){
	jc[0]=1;
	for(int i=1;i<=K;i++) jc[i]=jc[i-1]*(ll)i%ha;
	for(int i=0;i<=K;i++){
		a[i]=ksm(i,K)*(ll)ksm(jc[i],ha-2)%ha;
		if(i&1) b[i]=ha-ksm(jc[i],ha-2);
		else b[i]=ksm(jc[i],ha-2);
	}
	M=K<<1;
	for(N=1;N<=M;N<<=1) l++;
	for(int i=0;i<N;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
}

inline int solve(){
	int ans=0;
	init();
	
	NTT(a,1),NTT(b,1);
	for(int i=0;i<N;i++) a[i]=a[i]*(ll)b[i]%ha;
	INV=ksm(N,ha-2),NTT(a,-1);
	
	int base=1;
	for(int i=0;i<=K;base=base*(ll)(n-i)%ha,i++){
		ans=add(ans,a[i]*(ll)base%ha*(ll)ksm(2,n-i)%ha);
	}
	return ans;
}

int main(){
	scanf("%d%d",&n,&K),n--;
	printf("%d\n",solve()*(ll)(n+1)%ha*(ll)ksm(2,n*(ll)(n-1)/2%(ha-1))%ha);
	return 0;
}

  

bzoj 5093: [Lydsy1711月賽]圖的價值