zoukankan      html  css  js  c++  java
  • BZOJ2339 HNOI2011卡农(动态规划+组合数学)

      考虑有序选择各子集,最后除以m!即可。设f[i]为选i个子集的合法方案数。

      对f[i]考虑容斥,先只满足所有元素出现次数为偶数。确定前i-1个子集后第i个子集是确定的,那么方案数为A(2n-1,i-1)。

      显然不能为空集,于是去掉前i-1个已经满足限制的方案,也即f[i-1]。

      然后去掉第i个子集和之前重复的情况。显然如果有重复,将这两个去掉后仍然是合法的。那么方案数为f[i-2]*(i-1)*(2n-1-(i-2))。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define P 100000007
    #define N 1000010
    int n,m,f[N],inv[N],p,A[N];
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2339.in","r",stdin);
        freopen("bzoj2339.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();
        p=1;for (int i=1;i<=n;i++) p=(p<<1)%P;p--;
        inv[1]=1;
        for (int i=2;i<=m;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
        for (int i=2;i<=m;i++) inv[i]=1ll*inv[i]*inv[i-1]%P;
        A[0]=1;for (int i=1;i<=m;i++) A[i]=1ll*A[i-1]*(p-i+1+P)%P;
        f[0]=1;f[1]=0;
        for (int i=2;i<=m;i++) f[i]=((A[i-1]-f[i-1]+P)%P-1ll*f[i-2]*(i-1)%P*(p-i+2+P)%P+P)%P;
        cout<<1ll*f[m]*inv[m]%P;
        return 0;
    }
  • 相关阅读:
    分析 ajax 请求并抓取 “今日头条的街拍图”
    requests + 正则表达式 获取 ‘猫眼电影top100’。
    爬虫基础(暂缓更新)
    Git 操作笔记:分布式版本控制系统
    python补充
    python基础
    8.最佳电影聚类分析
    文本分析 笔记
    7.文档聚类
    5.词项相似度分析
  • 原文地址:https://www.cnblogs.com/Gloid/p/9649609.html
Copyright © 2011-2022 走看看