标签:pre www 学习笔记 怎么 ase cout include var main
设 \(F(x)\) 为斐波那契数列的生成函数,\(G(x)\) 为答案的生成函数,显然:
即 \(G(x)=\frac{1}{1-F(x)}\)
由 \(F(x)=\frac{x}{1-x-x^2}\) 可得,\(G(x)=\frac{1-x-x^2}{1-2x-x^2}=1+\frac{x}{1-2x-x^2}\)
然后按求斐波那契的通项公式那样去求
把分母给拆分了
\(G(x)=1+\frac{x}{(1-\phi_1 x)(1-\phi_2 x)}\)
解方程可以解出 \(\phi_1 = 1-\sqrt{2},\phi_2=1+\sqrt{2}\)
然后把 \(G(x)\) 拆分一下,得:
其中
那么
得出方程式
解得 \(\begin{cases} a=\frac{-1}{2\sqrt{2}}\\ b=\frac{1}{2\sqrt{2}} \end{cases}\)
那么第 \(n\) 项的通项公式显然就是 \(\frac{(1+\sqrt{2})^n-(1-\sqrt{2})^n}{2\sqrt{2}}\)
至于 \(\sqrt{2} \operatorname{mod} 10^9+7\) 怎么去做,详见我的二次剩余学习笔记
发现 \(n\) 好像很大的样子,直接用降幂大法去做,即令 \(n\mod \varphi(10^9+7)+\varphi(10^9+7)\)
以下是优美的代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll Sqrt2=5971360,mod=1e9+7,phi=1e9+6;//为了防抄袭把Sqrt2去掉了一个数(
ll ksm(ll b,int n){
ll res=1;
while(n){
if(n&1) res=res*b%mod;
b=b*b%mod; n>>=1;
}
return res;
}
int main(){
string s;
ll n=0,fl=0;
cin>>s;
int len=s.size();
for(int i=0;i<len;++i){
n=n*10+s[i]-‘0‘;
if(n>=phi) fl=1;
if(fl) n%=phi;
}
if(fl) n+=phi;
ll ans=(ksm(1+Sqrt2,n)-ksm(1-Sqrt2+mod,n)+mod)%mod*ksm((Sqrt2+Sqrt2)%mod,mod-2)%mod;
cout<<ans;
return 0;
}
标签:pre www 学习笔记 怎么 ase cout include var main
原文地址:https://www.cnblogs.com/limit-ak-ioi/p/13217264.html