zoukankan      html  css  js  c++  java
  • CCA的小球【容斥定理】

    题意

    给定 (n) 个小球,每个小球有颜色,要将它们摆成一行 。两个方案不同,当且仅当存在某个位置,两种方案摆在这个位置的小球颜色不同。一个方案合法,当且仅当不存在任意两个位置相邻的小球颜色相同,求合法方案数对 (10^9+7) 取模后的值。((nleq 10^6)),每种颜色出现的次数 (leq 2)
    链接:https://ac.nowcoder.com/acm/contest/11168/D

    分析

    发现合法方案不好求解。因此,可以求出不合法的方案的数量,从总方案中减去即为合法方案数。在计算不合法方案数时,对相邻同色球的对数进行讨论。会发现出现重复,采用容斥定理来去重。计算是注意可重集合的排列数计算。代码实现时,一开始使用离散化的方式,但一直错。换成直接排序判断相邻是否相同就过了。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    const int mod=1e9+7;
    const int N=1e6+6;
    int a[N],fac[N],inv[N],num[N];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        fac[0]=1,inv[1]=1;
        for(int i=1;i<=n;i++) fac[i]=1LL*fac[i-1]*i%mod;
        for(int i=2;i<=n;i++) inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
        sort(a+1,a+1+n);
        int ans=0,m=0,pw=1,res=1;
        for(int i=2;i<=n;i++)
            if(a[i]==a[i-1]) m++;
        for(int i=1;i<=m;i++) pw=1LL*pw*inv[2]%mod;
        ans=1LL*fac[n]*pw%mod;
        for(int i=1;i<=m;i++)
        {
            res=1LL*res*(m-i+1)%mod;
            res=1LL*res*inv[i]%mod;
            pw=2LL*pw%mod;
            if(i&1) ans=(ans-1LL*res*fac[n-i]%mod*pw%mod)%mod;
            else ans=(ans+1LL*res*fac[n-i]%mod*pw%mod)%mod;
            ans=(ans+mod)%mod;
        }
        printf("%d
    ",(ans+mod)%mod);
        return 0;
    }
    
    
  • 相关阅读:
    ipad mini2 ios7 磁盘分析文件夹大小
    Qt设置horizontal line 和vertical line 的颜色
    剖析QMenu & Qt完全定制化菜单
    Django--Auth 模块
    Django --ORM常用的字段和参数 多对多创建形式
    Django--Ajax 提交
    Django--CSRF 跨站请求伪造
    Django--Session 操作
    css
    pycharm格式化代码 常用快捷键
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/14536087.html
Copyright © 2011-2022 走看看