整数的lqp拆分 题解

Posted limit-ak-ioi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整数的lqp拆分 题解相关的知识,希望对你有一定的参考价值。

(F(x)) 为斐波那契数列的生成函数,(G(x)) 为答案的生成函数,显然:

[G(x)=sum_{i=1}^{∞}F(x)^i ]

(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)) 拆分一下,得:

[G(x)=1+frac{a}{1-phi_1 x}+frac{b}{1-phi_2 x} ]

其中

[a imes (1-phi_2 x)+b imes (1-phi_1 x)=x]

那么

[a-a imes phi_2 x+b-b imes phi_1 x=x ]

得出方程式

[egin{cases} a+b=0 a imes phi_2+b imes phi_1=-1 end{cases} ]

解得 (egin{cases} a=frac{-1}{2sqrt{2}}\\ b=frac{1}{2sqrt{2}} end{cases})

那么第 (n) 项的通项公式显然就是 (frac{(1+sqrt{2})^n-(1-sqrt{2})^n}{2sqrt{2}})

至于 (sqrt{2} operatorname{mod} 10^9+7) 怎么去做,详见我的二次剩余学习笔记

发现 (n) 好像很大的样子,直接用降幂大法去做,即令 (nmod 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;
}

以上是关于整数的lqp拆分 题解的主要内容,如果未能解决你的问题,请参考以下文章

整数的lqp拆分

bzoj2173 整数的lqp拆分

[bzoj2173]整数的lqp拆分

《LeetCode之每日一题》:58.整数拆分

搜索入门练习题4 数的拆分 题解

LeetCode 179. 最大数c++/java详细题解