zoukankan      html  css  js  c++  java
  • 排列 [HNOI2011]卡农

    问题 A: [HNOI2011]卡农
    时间限制: 1 Sec 内存限制: 128 MB
    题目描述
    这里写图片描述
    共有2^n-1种片段组合方式。设数字i出现次数ai,选i个片段是合法总方案数为fi。
    这里我们先按不同排列方式为不同情况。
    那么对于A(2^n-1,i-1)就是i个位置上有i-1个位置上放上了片段,有两种情况,
    1,这i-1个片段已满足要求,不合法。
    2,这i-1个片段不满足要求,那么有唯一一个片段使之合法。
    但是考虑放i-2个片段时是满足的,加了任意一个其他片段后是i-1个,之后又加了一个相同的片段使之满足,那他就重复了,不合法。所以要把这两种情况去掉。
    第一种减去fi-1,第二种减fi-2*(i-1)*(2^n-1-(i-2))。
    那我解释一下,对于每种放i-2个时的满足情况,可以放剩余2^n-1-(i-2)个片段中的任一个,并且有i-1个位置可以放。那现在再结合上面的看。
    最后除以m!(因为不同排列算一个)

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define mod 100000007
    #define N 1000005
    using namespace std;
    ll n,m,A[N],f[N],xp=1,ans=1;
    inline ll cheng(ll x,ll n)
    {
        ll s=1;x%=mod;
        while(n)
        {
            if(n&1)s=s*x%mod;
            x=x*x%mod;
            n/=2;
        }
        return s;
    }
    int main()
    {
       // freopen("canon.in","r",stdin);
    //  freopen("canon.out","w",stdout);
        cin>>n>>m;A[0]=1;f[0]=1;
        xp=cheng(2ll,n);xp--;if(xp<0)xp+=mod;
        for(int i=1;i<=m;i++)A[i]=A[i-1]*(xp-i+1)%mod;
        for(int i=3;i<=m;i++)f[i]=(A[i-1]-f[i-1])%mod-(f[i-2]*(xp-i+2)%mod*(i-1))%mod,f[i]%=mod;
        for(int i=2;i<=m;i++)ans=(ans*i)%mod;
        ans=cheng(ans,mod-2);//求逆元
        ans=(ans*f[m]%mod+mod)%mod;
        cout<<ans;
    }
  • 相关阅读:
    ci中使用smarty
    php curl用法
    百万级访问网站前期的技术准备
    enctype="multipart/formdata" 文件上传
    【转】lnmp配置记录
    ActionScript实现两直线相交弧跨越算法
    Adobe Flex迷你教程 — ActionScript实现二维向量运算
    U盘启动安装Linux(转)
    Adobe Flex迷你教程 — 实现类似新浪微博评论消息容器
    Adobe Flex迷你教程 — 让Graphics的线响应事件。
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632689.html
Copyright © 2011-2022 走看看