博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 2339: [HNOI2011]卡农
阅读量:4659 次
发布时间:2019-06-09

本文共 1094 字,大约阅读时间需要 3 分钟。

Description

题面

Solution

比较难想....

我们先考虑去掉无序的这个条件,改为有序,最后除 \(m!\) 即可
\(f[i]\) 表示前\(i\)个合法集合的方案数
明确一点:
如果前\(i-1\)个集合已经确定,并且前\(i\)个是合法的,那么第\(i\)就是确定的,所以是一一对应的关系,如果不考虑重复和空集的情况,那么总方案数就是 \(A_{2^{n}-1}^{i-1}\)
考虑去掉不合法的:
1.当前集合为空集,方案数为 \(f[i-1]\)
2.有两个集合相同,那么去掉这两个集合的方案数是 \(f[i-2]\),由于重复的那个位置可以取 \(i-1\) 个位置,且只与这个集合重复,而不与其他集合重复,所以两个集合可以取 \(2^{n}-1-(i-2)\)
然后直接递推即可,\(log\)求逆的话,复杂度就是 \(O(n*logn)\)

#include
using namespace std;typedef long long ll;const int N=1e6+5,mod=1e8+7;int qm(int x,int k){ int sum=1; while(k){ if(k&1)sum=1ll*sum*x%mod; x=1ll*x*x%mod;k>>=1; } return sum;}int f[N],Fac[N];int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); int n,m,x,t,jc=1; cin>>n>>m; t=qm(2,n);Fac[1]=x=(t-1+mod)%mod; Fac[0]=1; for(int i=1;i<=m;i++) jc=1ll*i*jc%mod,Fac[i]=1ll*Fac[i-1]*x%mod,x=(x-1+mod)%mod; f[0]=1;f[1]=0; for(int i=2;i<=m;i++){ f[i]=Fac[i-1]; f[i]=(f[i]-f[i-1]-1ll*f[i-2]*(i-1)%mod*(t-1-(i-2)))%mod; } if(f[m]<0)f[m]+=mod; f[m]=1ll*f[m]*qm(jc,mod-2)%mod; cout<
<

转载于:https://www.cnblogs.com/Yuzao/p/8445693.html

你可能感兴趣的文章