1. 程式人生 > 其它 >筆記-生成函式求解數列通項

筆記-生成函式求解數列通項

P4451 [國家集訓隊]整數的lqp拆分

生成函式入門題

眾所周知斐波那契數列有生成函式:\(F(x)=\frac{x}{1-x-x^2}\)

前置知識

這一部分推的式子貌似是錯的,但是方法沒錯(我也不想改了,後面 \(G\) 的式子也是對的。

根據生成函式求數列通項,拿斐波那契數列舉例。我們想要把上面那個式子湊成若干 \(\frac{1}{1-cx}\) 線性組合的形式。

\(\mathbb{R}\) 內對 \((1-x-x^2)\) 因式分解,得到 \((1-x-x^2)=(\frac{-1+\sqrt 5}{2}-x)(\frac{-1-\sqrt 5}{2}-x)\)。然後湊成 \(1-cx\)

的形式:\((1-\frac{\sqrt 5+1}{2}x)(1-\frac{1-\sqrt 5}{2}x)\)

接著我們待定係數 \(F(x)=\frac{x}{1-x-x^2}=\frac{a}{1-\frac{\sqrt 5+1}{2}x}+\frac{b}{1-\frac{\sqrt 5-1}{2}x}\),然後我們發現 \(a=\frac{1}{\sqrt 5}, b=\frac{-1}{\sqrt{5}}\)

然後就得到 \(F(x)=\frac{1}{\sqrt 5}(\frac{1}{1-\frac{\sqrt 5+1}{2}x}-\frac{1}{1-\frac{1-\sqrt 5}{2}x})\)

,根據 \(\sum\limits_{i=0}^{\infty}A(x)^i=\frac{1}{1-A(x)}\),得 \(F(x)=\frac{1}{\sqrt 5}\sum\limits_{i=0}^{\infty}((\frac{\sqrt 5+1}{2})^n-(\frac{1-\sqrt 5}{2})^n)x^n\)

於是 \(f_n=\frac{1}{\sqrt 5}((\frac{\sqrt 5+1}{2})^n-(\frac{1-\sqrt 5}{2})^n)\)


現在來看這道題,我們列舉拆成幾個數,得到答案 \(g_n\) 的生成函式:

\[\begin{aligned} G(x)[x^n]&=\sum\limits_{k=0}^{n}F(x)^k[x^n]\\ &=\frac{1}{1-\frac{1}{1-x-x^2}}[x^n]\\ &=\frac{1}{1-2x-x^2}[x^n]\\ \end{aligned} \]

再套用剛才的解法即可。

解出來:\(g_n=\frac{\sqrt 2}{4}((1+\sqrt 2)^n-(1-\sqrt 2)^n)\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll sqrt2=59713600;
template <typename T>
void read(T &x) {
	T flag=1;
	char ch=getchar();
	for (; '0'>ch||ch>'9'; ch=getchar()) if (ch=='-') flag=-1;
	for (x=0; '0'<=ch&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
	x*=flag;
}
char s[10005];
ll phi=mod-1, n;
ll ksm(ll a, ll b, ll m) {
	ll ret=1;
	while (b) {
		if (b&1) ret=ret*a%m;
		a=a*a%m;
		b>>=1;
	}
	return ret;
}
int main() {
	scanf("%s", s+1);
	int len=strlen(s+1);
	if (len==1&&(s[1]=='0'||s[1]=='1')) {
		printf("%d", s[1]-'0');
	}
	for (int i=1; i<=len; i++) {
		n=(n*10+s[i]-'0')%phi;
	}
	ll ans=(ksm(sqrt2+1, n, mod)-ksm(1-sqrt2, n, mod)+mod)%mod;
	ans=ans*sqrt2%mod;
	ans=ans*ksm(4, mod-2, mod)%mod;
	printf("%lld\n", ans);
	return 0;
}

提交記錄