zoukankan      html  css  js  c++  java
  • CF961G Partitions

    CF961G Partitions

    稍微想一下就可以列出下面的式子。

    [sum_{i=1}^{n}w_isum_{j=1}^{n}jinom{n-1}{j-1}egin{Bmatrix}n-j\k-1end{Bmatrix} ]

    可以打个暴力验证一下,发现式子对了,并且前面 (sum w_i) 可以最后乘。

    大概意思是统计每一个数对答案的贡献,枚举它所在集合的大小为 (j) ,然后补上 (j-1) 个数,最后乘上剩下 (n-j) 个数分成 (k-1) 个非空集合的方案数。

    暴力程序应该尽量短一些,并且写的快一点。

    const int N=1145;
    #define mod 1000000007
    inline int qpow(int n,int k){int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
    int n,k,w[N],S2[N][N],fac[N],ifc[N],ans;
    int comb(int n,int m){return n<m?0:1ll*fac[n]*ifc[m]%mod*ifc[n-m]%mod;}
    signed main(){
    	n=read(),k=read();
    	rep(i,1,n)w[i]=read();
    	S2[0][0]=1;rep(i,1,n)rep(j,1,i)S2[i][j]=(S2[i-1][j-1]+1ll*S2[i-1][j]*j%mod)%mod;
    	fac[0]=1;rep(i,1,n)fac[i]=1ll*i*fac[i-1]%mod;
    	ifc[n]=qpow(fac[n],mod-2);per(i,n-1,0)ifc[i]=1ll*ifc[i+1]*(i+1)%mod;
    	int tim=0,sum=0;
    	for(int j=1;j<=n;++j)tim=(tim+1ll*j*comb(n-1,j-1)%mod*S2[n-j][k-1]%mod)%mod;
    	for(int i=1;i<=n;++i)sum=(sum+w[i])%mod;
    	ans=1ll*tim*sum%mod;
    	cout<<ans<<'
    ';
    }
    

    所以目前的目标是,求出

    [sum_{i=1}^{n}iinom{n-1}{i-1}egin{Bmatrix}n-i\k-1end{Bmatrix}\ ]

    直接求一列斯特林数就能算了,只不过出题人不讲wood,mod=1e9+7 ,板子比较牛逼的人应该可以松过去。

    不过这个式子看着感觉可以化简,想了想没啥思路,就暴力把斯特林数拆了。

    斯特林数展开到组合数的式子:

    [egin{Bmatrix}n\mend{Bmatrix}=dfrac{1}{m!}sum_{i=0}^{m}(-1)^{m-i}inom{m}{i}i^n ]

    带进去

    [=sum_{i=1}^{n}iinom{n-1}{i-1}dfrac{1}{(k-1)!}sum_{j=0}^{k-1}(-1)^{k-1-j}inom{k-1}{j}j^{n-i}\ ]

    为了方便直接把 (k)(1) ,然后一波式子直接推到底。

    [sum_{i=1}^{n}iinom{n-1}{i-1}dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}j^{n-i}\ =dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}sum_{i=1}^{n}j^{n-i}iinom{n-1}{i-1}\ =dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}(sum_{i=1}^{n}j^{n-i}inom{n-1}{i-1}+sum_{i=1}^{n}j^{n-i}(i-1)inom{n-1}{i-1})\ =dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}(sum_{i=0}^{n-1}j^{n-1-i}inom{n-1}{i}+sum_{i=0}^{n-1}j^{n-1-i}iinom{n-1}{i})\ =dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}((1+j)^{n-1}+(n-1)sum_{i=0}^{n-1}j^{n-1-i}dfrac{i}{n-1}inom{n-1}{i})\ =dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}((1+j)^{n-1}+(n-1)sum_{i=0}^{n-1}j^{n-1-i}inom{n-2}{i-1})\ =dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}((1+j)^{n-1}+(n-1)sum_{i=0}^{n-2}j^{n-2-i}inom{n-2}{i})\ =dfrac{1}{k!}sum_{j=0}^{k}(-1)^{k-j}inom{k}{j}((1+j)^{n-1}+(n-1)(1+j)^{n-2})\ ]

    倒数第三步步用了个叫做吸收率的东西

    [inom{n}{m}=dfrac{n}{m}inom{n-1}{m-1}Leftrightarrow dfrac{m}{n}inom{n}{m}=inom{n-1}{m-1} ]

    现在可以 (O(klog k)) 算了。 (log) 应该是可以消掉的,不过意义不大。

    于是我们得到了一个把多项式科技吊起来打的方法,码量,常数全部吊打,除了思维难度(

    非常恶心的是,(n=1) 的时候,快速幂算 ((1+j)^{n-2}) 会TLE。我劝这个出题人耗子尾汁,已经不讲wood地卡了多项式就别搞这种corner case

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mkp(x,y) make_pair(x,y)
    #define pb(x) push_back(x)
    #define sz(v) (int)v.size()
    typedef long long LL;
    typedef double db;
    template<class T>bool ckmax(T&x,T y){return x<y?x=y,1:0;}
    template<class T>bool ckmin(T&x,T y){return x>y?x=y,1:0;}
    #define rep(i,x,y) for(int i=x,i##end=y;i<=i##end;++i)
    #define per(i,x,y) for(int i=x,i##end=y;i>=i##end;--i)
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    const int N=200005;
    #define mod 1000000007
    inline int qpow(int n,int k){if(k<0)return 0;int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
    int n,k,sum,fac[N],ifc[N],ans;
    int comb(int n,int m){return n<m?0:1ll*fac[n]*ifc[m]%mod*ifc[n-m]%mod;}
    signed main(){
    	n=read(),k=read()-1;
    	rep(i,1,n)sum=(sum+read())%mod;
    	fac[0]=1;rep(i,1,k)fac[i]=1ll*i*fac[i-1]%mod;
    	ifc[k]=qpow(fac[k],mod-2);per(i,k-1,0)ifc[i]=1ll*ifc[i+1]*(i+1)%mod;
    	for(int i=0;i<=k;++i){
    		int tmp=1ll*comb(k,i)*(qpow(1+i,n-1)+1ll*(n-1)*qpow(1+i,n-2)%mod)%mod;
    		(k-i)&1?ans=(ans+mod-tmp)%mod:ans=(ans+tmp)%mod;
    	}
    	ans=1ll*ans*ifc[k]%mod*sum%mod;
    	cout<<ans<<'
    ';
    }
    
  • 相关阅读:
    trailRenderer
    通过sysobjects快速查找SQLServer中是否有某个表、视图、存储过程等对象实操
    浅谈信息系统(IT)项目管理-序幕
    使用open xml 判断sharepoint文档是否损坏
    Sharepoint the file is locked for use domainuser edit.文件被锁定,解锁方式
    sharepoint 列表库指定序号规则
    Biztalk 宏
    Biztalk 在流程中定义将消息保存为文件的文件名
    Biztalk 2013 新特性简介(英)
    devexpress gridview,selectedrowchanged
  • 原文地址:https://www.cnblogs.com/zzctommy/p/14279102.html
Copyright © 2011-2022 走看看