zoukankan      html  css  js  c++  java
  • [HAOI2018]染色

    题面

    神仙题。

    (lim=min{[n/s,m]}),容斥之后暴力推式子,有

    [ans=m!n!sum_{i=0}^{lim}frac{(m-i)^{n-is}}{(s!)^i(m-i)!(n-is)!}sum_{i=0}^{j}frac{w_i}{i!}frac{(-1)^{j-i}}{(j-i)!} ]

    (NTT)即可。

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define FILE "a"
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1004535809;
    const int N=10000010;
    const dd pi=acos(-1);
    const int inf=2147483647;
    const ll INF=1e18+1;
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    
    il void file(){
    	srand(time(NULL)+rand());
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    }
    
    il int poww(int a,int b){
    	RG int ret=1;
    	for(;b;b>>=1,a=1ll*a*a%mod)
    		if(b&1)ret=1ll*ret*a%mod;
    	return ret;
    }
    
    int invf[N],fac[N];
    il void init(){
    	invf[0]=fac[0]=1;
    	for(RG int i=1;i<N;i++)fac[i]=1ll*fac[i-1]*i%mod;
    	invf[N-1]=poww(fac[N-1],mod-2);
    	for(RG int i=N-2;i;i--)invf[i]=1ll*invf[i+1]*(i+1)%mod;
    }
    
    int l,r[N];
    il void NTT(int *a,int n,int opt){
    	for(l=0;(1<<l)<n;l++);n=(1<<l);
    	for(RG int i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    	for(RG int i=0;i<n;i++)if(i<r[i])swap(a[i],a[r[i]]);
    	for(RG int i=2;i<=n;i<<=1){
    		RG int wn=poww(opt==1?3:(mod+1)/3,(mod-1)/i);
    		for(RG int j=0;j<n;j+=i){
    			RG int w=1;
    			for(RG int k=j;k<j+(i>>1);k++,w=1ll*w*wn%mod){
    				RG int x=1ll*a[k+(i>>1)]*w%mod;
    				a[k+(i>>1)]=(a[k]-x+mod)%mod;
    				a[k]=(a[k]+x)%mod;
    			}
    		}
    	}
    	if(opt==-1)
    		for(RG int i=0,rv=poww(n,mod-2);i<n;i++)
    			a[i]=1ll*a[i]*rv%mod;
    }
    
    int n,m,s,lim,w[N],f[N],g[N],len,ans;
    int main()
    {
    	n=read();m=read();s=read();lim=min(n/s,m);init();
    	for(RG int i=0;i<=m;i++)w[i]=read();
    	for(RG int i=0;i<=lim;i++)f[i]=1ll*w[i]*invf[i]%mod;
    	for(RG int i=0;i<=lim;i++)g[i]=1ll*((i&1)?(mod-1):1)*invf[i]%mod;
    	for(len=1;len<=(lim<<1);len<<=1);
    	
    	NTT(f,len,1);NTT(g,len,1);
    	for(RG int i=0;i<len;i++)f[i]=1ll*f[i]*g[i]%mod;
    	NTT(f,len,-1);
    	
    	for(RG int i=0;i<=lim;i++)
    		(ans+=1ll*f[i]*poww(m-i,n-i*s)%mod*poww(invf[s],i)%mod*invf[m-i]%mod*invf[n-i*s]%mod)%=mod;
    	printf("%lld
    ",1ll*ans*fac[n]%mod*fac[m]%mod);
    	return 0;
    }
    
    
  • 相关阅读:
    最近迷上用dvd字幕学习英语
    原始套接字
    c语言socket编程
    inet_aton和inet_network和inet_addr三者比较
    用man来查找c函数库
    ubuntu的系统日志配置文件的位置
    复制文件
    vim复制粘贴解密(转)
    vim的自动补齐功能
    两个数据结构ip和tcphdr
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9317399.html
Copyright © 2011-2022 走看看