• bzoj2339 [HNOI2011]卡农


    Description

    正解:数学。

    这种数学题自己根本就想不到啊。。

    首先我们可以把片段看成有序的,只要最后除一下$m!$就行了。

    然后我们考虑$m$个片段的所有情况(包括不合法的)为$A_{2^{n}-1}^{m-1}$。

    当前$m-1$个片段确定以后,第$m$个片段肯定也能确定了。

    上面考虑到了每个数必须出现偶数次,但是没有考虑第$m$个片段是空集和与前$m-1$个片段重复的情况。

    那么我们设$f[m]$表示$m$个片段的合法情况,考虑怎么去掉空集和重复的情况。

    当第$m$个片段是空集时,显然,这是因为前$m-1$个片段已经是合法情况,所以才有这种情况,那么减去$f[m-1]$就行了。

    当第$m$个片段与前面某一片段重复时,我们可以枚举这是第几个片段,总共有$m-1$个这样的片段。

    于是拿掉这两个片段以后,剩下的$m-2$个片段又是合法情况了,再考虑这两个片段的方案数,可以得到我们需要减去的就是$(m-1)*f[m-2]*[2^{n}-1-(i-2)]$。

    于是这道题我们就做完了。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define rhl (100000007)
     6 #define N (1000010)
     7 
     8 using namespace std;
     9 
    10 ll f[N],g[N],bin,fac,n,m;
    11 
    12 il ll qpow(RG ll a,RG ll b){
    13   RG ll ans=1;
    14   while (b){
    15     if (b&1) ans=ans*a%rhl;
    16     a=a*a%rhl,b>>=1;
    17   }
    18   return ans;
    19 }
    20 
    21 int main(){
    22 #ifndef ONLINE_JUDGE
    23   freopen("canon.in","r",stdin);
    24   freopen("canon.out","w",stdout);
    25 #endif
    26   cin>>n>>m,bin=(qpow(2,n)-1+rhl)%rhl,g[0]=fac=1;
    27   for (RG ll i=1;i<=m;++i) g[i]=g[i-1]*(bin-i+1+rhl)%rhl,fac=fac*i%rhl;
    28   for (RG ll i=3;i<=m;++i)
    29     f[i]=(g[i-1]-f[i-1]+rhl-(i-1+rhl)*f[i-2]%rhl*(bin-i+2+rhl)%rhl+rhl)%rhl;
    30   cout<<f[m]*qpow(fac,rhl-2)%rhl; return 0;
    31 }
  • 相关阅读:
    单片机八位时钟
    共阴数码管断码与位码
    PCB自己做一个原理图模版
    Mongodb在Linux下的安装和启动和配置
    linux下用phpize给PHP动态添加扩展
    微信支付JS各种调试问题
    秒速插入百万测试数据MYSQL,提供你玩玩大数据!
    金子的PHP之禅(函数篇四)
    linux下面查找某个字符或者文件
    金子的PHP之禅(PHP运算符三)
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7526306.html
Copyright © 2020-2023  润新知