zoukankan      html  css  js  c++  java
  • 【BZOJ2339】【HNOI2011】卡农

    ""

    题解:

      首先用二进制表示每个音阶是否使用,那么共有$2^{n}-1$(空集不可行)种片段,用$a_{i}$来表示每个片段,问题就是求满足$a_{1}left (xor ight)a_{2}left (xor ight)......left (xor ight)a_{m}==0&&a_{i}!=a_{j},1<=i<j<=m$的方案数,我们用$f_{i}$表示片段数为i时,且满足前面式子的答案。

      那么首先我们在选取i个片段时,必然是由前i-1个片段决定的,所以共有$A_{2^{n}-1}^{i-1}$种选取方案。其中若i-1个时已满足其异或和为0,那么此时是不合法的,所以需要减去$f_{i-1}$,考虑出现重复的情况,因为出现了重复,又有异或的逆运算就是本身,这也就意味着除去两个重复的片段的i-2个片段已经满足其异或和为0,而这个重复的片段在i-1个片段中的位置有i-1种,而这个重复的片段的值又可以在除去i-2个片段的集合中任意选取。

      所以得到递推式:

      $$f_{i}=A_{2^{n}-1}^{i-1}-f_{i-1}-f_{i-2}*(2^{n}-1-i+2)*(i-1)$$

      又由于不允许有重复,在最后除去$m!$即可。

     

     1 #include<cstdio>
     2 typedef long long ll;
     3 const ll mod=100000007;
     4 const int N=1000100;
     5 ll n,m;
     6 ll powmod(ll a,ll b){
     7     ll ans=1;
     8     a%=mod;
     9     for(;b;b>>=1,a=a*a%mod)
    10         if(b&1) ans=ans*a%mod;
    11     return ans;
    12 }
    13 ll tot;
    14 ll jie;
    15 ll fac[N];
    16 inline void init(){
    17     fac[0]=1;
    18     for(ll i=1;i<=m;i++)    
    19         fac[i]=fac[i-1]*(tot-i+1)%mod;
    20 }
    21  
    22 ll f[N];
    23 int main(){
    24     scanf("%lld%lld",&n,&m);
    25     tot=powmod(2LL,n);
    26     tot--;
    27     if(tot<0)   tot+=mod;
    28     init();
    29     for(ll i=3;i<=m;i++){
    30         f[i]=(fac[i-1]-f[i-1])%mod-f[i-2]*(i-1)%mod*(tot-i+2)%mod;
    31         f[i]%=mod;
    32     }
    33     ll tt=1;
    34     for(ll i=1;i<=m;++i)
    35         tt=tt*i%mod;
    36     tt=powmod(tt,mod-2);
    37     printf("%lld
    ",(f[m]*tt%mod+mod)%mod);
    38 }
  • 相关阅读:
    route-over VS mesh-under
    IOS算法(三)之插入排序
    GitHub学习笔记
    Python-面向对象 (二 继承)
    POJ 3518 Prime Gap(素数题)
    struts2的总体回想(ACTION、拦截器、值栈、OGNL表达式、ModelDriven方案等)
    first move advantage_百度搜索
    【绿茶书情】:《SOHO小报》和《凤…
    潘石屹的SOHO小报猝死
    ASP.NET Hashtable输出JSON格式数据
  • 原文地址:https://www.cnblogs.com/Troywar/p/7434460.html
Copyright © 2011-2022 走看看