听rqy说可以用生成函数做,感觉比较有意思
我们考虑在DP转移的时候,
$5,7,9$这三个数是没有限制的
因此他们出现的次数用01串表示的话就是$1111111111111111......$
$3,5$这两个数只能出现偶数次且必须出现
因此他们出现的次数用01串表示的话是$0010101010101010101....$
因为是组合计数问题,我们考虑用指数型生成函数来搞
对于第一个肯定就是$e^x$
对于第二个,我们首先用$frac{e^x+e^{-x}}{2}$构造出$1010101010.....$
然后再减个$1$就好了
这样的话我们不难得到答案的方案实际就是
$left( e^{x} ight) ^{3}left( dfrac {e^{x}+e^{-x}}{2}-1 ight) ^{2}$
然后暴力推推推就可以得到
$dfrac {1}{4}e^{5x}+dfrac {1}{4}e+dfrac {6}{4}e^{3x}-dfrac {4}{4}e^{4x}-dfrac {4}{4}e^{2x}$
然后快速幂搞一搞就好了
生成函数好神奇QWQ。。。
#include<cstdio> #include<iostream> #define int long long using namespace std; const int MAXN=1e6+10; const int mod=1e9+7; int a[MAXN]={0,5,1,3,4,2}; int k[MAXN]={0,1,1,6,-4,-4}; int fastpow(int a,int p) { int base=1; while(p) { if(p&1) base=(base*a)%mod; a=(a*a)%mod; p>>=1; } return base%mod; } main() { int N,ans=0; cin>>N; for(int i=1;i<=5;i++) ans =( ans + fastpow(a[i], N) * k[i] ) %mod; cout<<( ans * ( (mod + 1) / 4 ) %mod + mod ) %mod; return 0; }