【BZOJ】2339: [HNOI2011]卡農 -組合計數
阿新 • • 發佈:2018-11-26
傳送門:bzoj2339
題解
神仙 。
本質不同有點麻煩,考慮列舉方案之後除
即可(???這一步就沒想到)
設 表示長度為 的滿足條件的音樂個數(排列方式不同算不同)。考慮用容斥的方法計數。
假設已知前 個片段,第 個片段就是唯一確定的,共 種方案。
第 個片段為空集的方案數為 ,與前 個片段中某個重複的概率為 (刪去與它相同的後方案數為 , 的方案數為 ,任選前面一個片段與它重複( )。
所以轉移方程為:
初始化 。
程式碼
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100,mod=1e8+7;
typedef long long ll;
int n,m,lim,f[N],a[N],frc;
inline int dc(int x,int y){x-=y;return x<0?x+mod:x;}
inline int ad(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int fp(int x,int y)
{
int re=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) re=(ll)re*x%mod;
return re;
}
int main(){
int i,j;
scanf("%d%d",&n,&m);
a[1]=lim=dc(fp(2,n),1);frc=1;
for(i=1;i<m;++i) a[i+1]=(ll)a[i]*dc(lim,i)%mod;
for(i=2;i<=m;++i) frc=(ll)frc*i%mod;
f[1]=0;f[0]=1;
for(i=2;i<=m;++i)
f[i]=dc(a[i-1],ad(f[i-1],(ll)f[i-2]*(i-1)%mod*(ll)dc(lim,i-2)%mod));
printf("%d",(ll)f[m]*fp(frc,mod-2)%mod);
return 0;
}