一道组合意义题

CF961G Partitions

题意:自己看。懒得写了。

在深切感受到一个压根不接受核的人找一个核狗要日推的痛苦之后我看到了这个东西。

首先看见这种数数题直接翻一下题解看代码长度,发现第一篇人畜无害的正常推式子题代码长度于是放心推。

然后我们可以列出来这么一个人畜无害的式子:

i=1nwij=1nj(n1j1){njk1}

球球了我真的很不想在大晚上的时候还要写一车注解。直接把后边系数扒出来。

i=1ni(n1i1){nik1}=i=1ni(n1i1)1(k1)!j=0k1(1)k1j(k1j)jni=j=0k1(1)k1j(k1j)!1j!i=1ni(n1i1)jnii=1ni(n1i1)jni=i=1n(i1)(n1i1)jni+i=1n(n1i1)jni=(n1)i=1n(n2i2)jni+i=1n(n1i1)jni=(n1)(j+1)n2+(j+1)n1=(n+j)(j+1)n2

所以系数就是

j=0k1(1)k1j(k1j)!n+jj!(j+1)n2

完事。特判 n=k=1

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int mod=1000000007;
int n,k,ans,sum,jc[200010],inv[200010];
int qpow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=1ll*ans*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&k);jc[0]=inv[0]=1;
    for(int i=1;i<=n;i++)jc[i]=1ll*jc[i-1]*i%mod;
    inv[n]=qpow(jc[n],mod-2);
    for(int i=n-1;i>=1;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod;
    for(int i=1;i<=n;i++){
        int x;scanf("%d",&x);sum=(sum+x)%mod;
    }
    if(n==1&&k==1){
        printf("%d\n",sum);return 0;
    }
    for(int j=0;j<k;j++){
        ans=(ans+1ll*((k-j&1)?1:mod-1)*inv[k-j-1]%mod*inv[j]%mod*(n+j)%mod*qpow(j+1,n-2))%mod;
    }
    ans=1ll*ans*sum%mod;
    printf("%d\n",ans);
    return 0;
}

然而没有完全完。

看了看题解发现了标题的玄妙。

首先我们这个东西可以变成这所有的分组方案中共有多少元素和 i 分在一组。那么 i 自己对自己的贡献显然是 {nk}。考虑其他元素,可以看做强制和 i 绑定,这样还有 n1 个元素,那么总贡献就是

{nk}+(n1){n1k}

拆一下是和上边一坨一样的东西。

posted @   gtm1514  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示