引
众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则。
我还真不知道
解法
做计数DP的题先观察性质;
性质1:
由于一段音乐每种音符被奏响的次数为偶数,
那么我们如果确定了前
m
−
1
m-1
m−1个集合那么第
m
m
m个集合就随之确定了(注意第
m
m
m个集合是最后确定的集合)
性质2:
集合不可为
∅
\empty
∅ 且对于任意两个选出的集合
A
A
A和
B
B
B,有
A
≠
B
A\ne B
A=B
设计状态
f i : 前 i 个集合合法可得到的合法方案数 f_i:前i个集合合法可得到的合法方案数 fi:前i个集合合法可得到的合法方案数
状态转移
之后我们考虑容斥
显然
f
i
=
C
2
n
−
1
m
f_i=C_{2^{n}-1}^{m}
fi=C2n−1m
根据性质1有
f
i
=
C
2
n
−
1
m
−
1
f_i=C_{2^{n}-1}^{m-1}
fi=C2n−1m−1
考虑集合为空的情况:
显然为
f
i
−
1
f_{i-1}
fi−1
而后是重复的情况:
为
f
i
−
2
∗
(
2
n
−
1
−
(
i
−
2
)
)
f_{i-2}*(2^n-1-(i-2))
fi−2∗(2n−1−(i−2))
再仔细想想,每种方案会被重算i次,比如:
{
{
1
,
2
}
,
{
2
,
3
}
}
\{\{1,2\},\{2,3\}\}
{{1,2},{2,3}}可以由
{
1
,
2
}
\{1,2\}
{1,2}或
{
2
,
3
}
\{2,3\}
{2,3}转移而来
最后:
f
i
=
C
2
n
−
1
m
−
1
−
f
i
−
1
−
f
i
−
2
∗
(
2
n
−
1
−
(
i
−
2
)
)
i
f_i=\frac{C_{2^{n}-1}^{m-1}-f_{i-1}-f_{i-2}*(2^n-1-(i-2))}{i}
fi=iC2n−1m−1−fi−1−fi−2∗(2n−1−(i−2))
code:
#include<bits/stdc++.h>
using namespace std;
template<class T>inline void read(T &x){
x=0;
char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))x=x*10+(c&15),c=getchar();
}
typedef long long ll;
const int N=1e6+7,mod=1e8+7;
int n,m,x,f[N],C;
int qpow(int a,int b=mod-2){
int s=1;
for(;b;b>>=1,a=(ll)a*a%mod)if(b&1)s=(ll)s*a%mod;
return s;
}
int main(){
read(n),read(m),x=qpow(2,n)-1;
if(x<0)x+=mod;
C=(ll)x*(x+mod-1)%mod*qpow(2)%mod;
for(int i=3;i<=m;i++)
f[i]=((C-f[i-1]-(ll)f[i-2]*((x-i+2+mod)%mod)%mod)%mod+mod)%mod*qpow(i)%mod,C=(ll)C*(x-i+1+mod)%mod*qpow(i)%mod;
printf("%d\n",f[m]);
}