• BZOJ 4710: [Jsoi2011]分特产 [容斥原理]


    4710: [Jsoi2011]分特产

    题意:m种物品分给n个同学,每个同学至少有一个物品,求方案数


    对于每种物品是独立的,就是分成n组可以为空,然后可以用乘法原理合起来
    容斥容斥

    [每个同学至少一个=所有方案数-ge 1个同学没有+ge 2 个同学没有-... ]

    (ge i)个同学没有,我们拿出来i个同学(inom{n}{i})个方案,剩下就是每种物品分成(n-i)组再乘起来罢了...


    ```cpp #include #include #include #include using namespace std; typedef long long ll; const int N=5005, P=1e9+7; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; }

    int n, m, c[N];
    ll inv[N], fac[N], facInv[N];
    inline ll C(int n, int m) {return fac[n]facInv[m]%P facInv[n-m]%P;}
    inline ll f(int c, int n) {return C(n+c-1, n-1);}
    void solve() {
    ll ans=0;
    for(int i=0; i<=n; i++) {
    ll t=1;
    for(int j=1; j<=m; j++) t=(t * f(c[j], n-i))%P;
    t = t
    C(n, i)%P;
    (ans += (i&1) ? -t : t) %=P;
    }
    printf("%lld ",(ans+P)%P);
    }
    int main() {
    //freopen("in","r",stdin);
    n=read(); m=read(); int lim=0;
    for(int i=1; i<=m; i++) c[i]=read(), lim=max(lim, c[i]);
    inv[1]=1; fac[0]=facInv[0]=1;
    for(int i=1; i<=n+lim; i++) {
    if(i!=1) inv[i] = (P-P/i)
    inv[P%i]%P;
    fac[i] = fac[i-1]i%P;
    facInv[i] = facInv[i-1]
    inv[i]%P;
    }
    solve();
    }

  • 相关阅读:
    测试中发现哪些bug
    兼容性测试
    接口测试基础
    Java基础概念
    Linux基础命令
    Selenium笔记
    常见软件测试类型分类
    性能测试类型
    网络基础题目
    常见测试方法
  • 原文地址:https://www.cnblogs.com/candy99/p/6616858.html
Copyright © 2020-2023  润新知