BZOJ-2173 整数的lqp拆分(生成函数)
题目描述
关于 \(n\) 的整数划分的定义为满足任意 \(m\geq 0,a_1,a_2,a_3,\cdots,a_m>0\),且 \(a_1+a_2+a_3+\cdots+a_m=n\) 的一个有序集合。
对于每个整数划分,定义这个划分的权值为 \(F_{a_1}\times F_{a_2}\times \cdots\times F_{a_m}\)(其中 \(F_0=0,F_1=1,F_n=F_{n-1}+F_{n-2}(n>1)\))。给出数字 \(n(n\leq 10^6)\),对于所有的划分,求它们的权值之和。
分析
已知斐波那契数的生成函数为:
拆分成 \(m\) 个数时,答案的生成函数为 \(F^{m}(x)\)(相当于把方案数最终算在了对应项的系数上)。
答案的生成函数为:
化简后面的分式:令 \(\frac{x}{1-2x-x^2}=A(\frac{1}{1-ax}-\frac{1}{1-bx})\)。
解得:\(A=\frac{\sqrt{2}}{4},a=1+\sqrt{2},b=1-\sqrt{2}\)。
即:
把 \(G(x)\) 的封闭形式转化成形式幂级数形式,则 \(g(n)\) 就是答案。
因此:
根据二次剩余:\(\sqrt{2}\equiv 59713600\pmod {10^9+7}\)。
答案为:
\(n\) 非常大,欧拉降幂一下,则答案为:
代码
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
inline long long read()
{
long long x=0,f=1;char ch=getchar();
long long p=mod-1;
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=(x*10ll+ch-48)%p;ch=getchar();}
return x*f;
}
long long quick_pow(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int main()
{
long long n=read();
long long ans1=1ll*59713600*250000002%mod;
long long ans2=(quick_pow(59713601,n)-quick_pow(940286408,n)+mod)%mod;
printf("%lld\n",ans1*ans2%mod);
return 0;
}
posted on 2020-12-04 17:32 DestinHistoire 阅读(78) 评论(0) 收藏 举报