zoukankan      html  css  js  c++  java
  • 【BZOJ5093】图的价值

    题面

    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

    题目分析

    显然(ans=ncdot 2^{frac {ncdot(n-1)}2-(n-1)}sumlimits_{i=0}^{n-1}i^kcdot inom{i}{n-1})

    其中,后面的求和式子与Codeforces 932E Team Work化简方式相同。

    [ans=ncdot 2^{frac {ncdot(n-1)}2-(n-1)}cdotsum_{i=0}^kegin{Bmatrix}k\iend{Bmatrix}iinom {n-1}i2^{n-1-i} ]

    用NTT预处理出(egin{Bmatrix}k\iend{Bmatrix}),答案便可直接计算。

    代码实现

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #include<iomanip>
    #include<cstdlib>
    #define MAXN 0x7fffffff
    typedef long long LL;
    const int N=200005,mod=998244353;
    using namespace std;
    inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;}
    int ksm(int x,int k){
    	int ret=1;
    	while(k){
    		if(k&1)ret=(LL)ret*x%mod;
    		x=(LL)x*x%mod,k>>=1;
    	}
    	return ret;
    }
    int fac[N],inv[N];
    int C(int n,int m){
    	if(n<m)return 0;
    	return (LL)fac[m]*inv[m]%mod;
    }
    
    int rev[N<<2];
    void NTT(int *a,int x,int K){
    	int n=(1<<x);
    	for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
    	for(int i=1;i<n;i<<=1){
    		int tmp=i<<1,wn=ksm(3,(mod-1)/tmp);
    		if(K==-1)wn=ksm(wn,mod-2);
    		for(int j=0;j<n;j+=tmp){
    			int w=1;
    			for(int k=0;k<i;k++,w=(LL)w*wn%mod){
    				int x=a[j+k],y=(LL)w*a[i+j+k]%mod;
    				a[j+k]=(x+y)%mod,a[i+j+k]=(x-y+mod)%mod;
    			} 
    		}
    	}
    	if(K==-1){
    		int inv=ksm(n,mod-2);
    		for(int i=0;i<n;i++)a[i]=(LL)a[i]*inv%mod;
    	}
    }
    
    int a[N<<2],b[N<<2]; 
    int main(){
    	int n=Getint(),K=Getint();
    	
    	fac[0]=1;for(int i=1;i<=K;i++)fac[i]=(LL)fac[i-1]*(n-i)%mod;
    	inv[0]=1;for(int i=1;i<=K;i++)inv[i]=(LL)inv[i-1]*ksm(i,mod-2)%mod;
    	
    	int x=ceil(log2(K<<1|1));
    	a[0]=1;for(int i=1,t=1;i<=K;i++,t=(LL)t*i%mod)a[i]=(((i&1)?-1:1)*ksm(t,mod-2)+mod)%mod,b[i]=(LL)ksm(i,K)*ksm(t,mod-2)%mod;
    	for(int i=0;i<(1<<x);i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<x-1);
    	
    	NTT(a,x,1),NTT(b,x,1);
    	for(int i=0;i<(1<<x);i++)a[i]=(LL)a[i]*b[i]%mod;
    	NTT(a,x,-1);
    	
    	int ans=0;
    	for(int i=0,t=1,lim=min(n-1,K);i<=lim;i++,t=(LL)t*i%mod)
    		ans=(ans+(LL)a[i]*t%mod*C(n-1,i)%mod*ksm(2,n-i-1)%mod)%mod;
    	cout<<((LL)ans*n%mod*ksm(2,((LL)n*(n-1)/2-(n-1))%(mod-1))%mod+mod)%mod;
    	return 0;
    }
    
  • 相关阅读:
    UVa 1151 Buy or Build【最小生成树】
    UVa 216 Getting in Line【枚举排列】
    UVa 729 The Hamming Distance Problem【枚举排列】
    HDU 5214 Movie【贪心】
    HDU 5223 GCD
    POJ 1144 Network【割顶】
    UVa 11025 The broken pedometer【枚举子集】
    HDU 2515 Yanghee 的算术【找规律】
    Java基本语法
    Java环境变量,jdk和jre的区别,面向对象语言编程
  • 原文地址:https://www.cnblogs.com/Emiya-wjk/p/10019575.html
Copyright © 2011-2022 走看看