bzoj2339 [HNOI2011]卡农
2017-09-15 14:31
204 查看
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)]$。
于是这道题我们就做完了。
#include <bits/stdc++.h> #define il inline #define RG register #define ll long long #define rhl (100000007) #define N (1000010) using namespace std; ll f ,g ,bin,fac,n,m; il ll qpow(RG ll a,RG ll b){ RG ll ans=1; while (b){ if (b&1) ans=ans*a%rhl; a=a*a%rhl,b>>=1; } return ans; } int main(){ #ifndef ONLINE_JUDGE freopen("canon.in","r",stdin); freopen("canon.out","w",stdout); #endif cin>>n>>m,bin=(qpow(2,n)-1+rhl)%rhl,g[0]=fac=1; for (RG ll i=1;i<=m;++i) g[i]=g[i-1]*(bin-i+1+rhl)%rhl,fac=fac*i%rhl; for (RG ll i=3;i<=m;++i) f[i]=(g[i-1]-f[i-1]+rhl-(i-1+rhl)*f[i-2]%rhl*(bin-i+2+rhl)%rhl+rhl)%rhl; cout<<f[m]*qpow(fac,rhl-2)%rhl; return 0; }
相关文章推荐
- bzoj2339[HNOI2011]卡农 dp+容斥
- 【bzoj2339】【HNOI2011】【卡农】【组合数学+dp】
- bzoj2339: [HNOI2011]卡农
- Bzoj2339--Hnoi2011卡农
- 【BZOJ2339】[HNOI2011]卡农 组合数+容斥
- [BZOJ2339][HNOI2011]卡农(DP+组合数学)
- BZOJ 2339 【HNOI2011】 卡农
- 【BZOJ2339】【HNOI2011】卡农
- BZOJ 2339: [HNOI2011]卡农
- [BZOJ 2339][HNOI 2011]卡农(组合数学)
- BZOJ 2339: [HNOI2011]卡农
- BZOJ2339: [HNOI2011]卡农
- BZOJ 2339 HNOI2011 卡农 组合数学
- bzoj 2339: [HNOI2011]卡农 组合数学+递推
- bzoj 2339: [HNOI2011]卡农
- BZOJ.2339.[HNOI2011]卡农(思路 DP 组合 容斥)
- 【bzoj2339】[HNOI2011]卡农 dp+容斥原理
- 2339: [HNOI2011]卡农
- [BZOJ]2326: [HNOI2011]数学作业 矩阵乘法
- 【BZOJ】2329: [HNOI2011]括号修复(splay+特殊的技巧)