Loading

题解-P4451 [国家集训队]整数的lqp拆分[*medium]

列出斐波那契数列的生成函数:\(G(x) = \frac{x}{1 - x - x^2}\)

答案的生成函数就是 \(\sum\limits_{i \ge 1} G(x)^i\)

\(F(x) = \sum\limits_{i \ge 1} G(x)^i = \frac{G(x)}{1 - G(x)} = \frac{\frac{x}{1 - x - x^2}}{1 - \frac{x}{1 - x - x^2}} = \frac{x}{1 - 2x - x^2}\)

\((1 - 2x - x^2) F(x) = x\)\(F(x) = 2 x F(x) + x^2 F(x) + x\)

得到递推柿 :\(f_1 = 1\)\(f_i = 2 f_{i - 1} + f_{i - 2}\)

这个可以矩乘,但是蒟蒻要介绍的是生成函数的方法。

\(F(x) = \frac{x}{1 - 2x - x^2}\)

因为 \(\frac{1}{1 - q \times x^k}\) 的第 \(t\) 项是很好算的,所以我们把他拆分成 \(\frac{a}{1 - x_1 x} + \frac{b}{1 - x_2 x}\) 的形式。

\(x_1, x_2\)\(x^2 - 2x - 1\) 的两根。\(x_1 = 1 + \sqrt {2}, x_2 = 1 - \sqrt {2}\)

\[x = (1 - x_1 x) \times b + (1 - x_2 x) \times a \]

\[\begin{cases} a + b = 0 \\ x_1 b + x_2 a = -1 \end{cases} \]

这是一次方程,解得 \(\begin{cases} a = \frac{1}{x_1 - x_2} \\ b = \frac{1}{x_2 - x_1} \end{cases}\)

那么得到了 \(F(x) = ( \frac{1}{x_1 - x_2} ) \frac{1}{1 - x_1 x} + ( \frac{1}{x_1 - x_2} ) \frac{1}{1 - x_2 x}\)

他的 \([x^n]\) 项就是 \(\frac{1}{x_1 - x_2} x_1^n + \frac{1}{x_2 - x_1} x_2^n = \frac{1}{x_1 - x_2} (x_1 ^ n - x_2 ^ n) = \frac{1}{2 \sqrt {2}} ( (1 + \sqrt{2})^n - (1 - \sqrt{2})^n)\)

\(\sqrt{2}\)\(10^9 + 7\)\(59713600\)\(940286407\)

于是费马小定理 + 快速幂就行了

#include<bits/stdc++.h>
#define L(i, j, k) for(int i = j, i##E = k; i <= i##E; i++) 
#define R(i, j, k) for(int i = j, i##E = k; i >= i##E; i--)
#define ll long long
#define ull unsigned long long 
#define pii pair<int, int>
#define db double
#define mkp make_pair
using namespace std;
const int N = 3e5 + 7;
const int mod = 1e9 + 7;
const int sqrt2 = 59713600;
int read() {
	int x = 0; char ch = getchar();
	while(ch < '0' || ch > '9') ch = getchar();
	while('0' <= ch && ch <= '9') x = ( (ll) x * 10 + (ch - '0') ) % (mod - 1), ch = getchar();
	return x;
}
int n;
int qpow(int x, int y = mod - 2) {
	int res = 1;
	for(; y; x = (ll) x * x % mod, y >>= 1) if(y & 1) res = (ll) res * x % mod;
	return res;
}
int main() {
	n = read();
	cout << (ll) qpow(2ll * sqrt2 % mod) * (qpow(1 + sqrt2, n) - qpow(1 - sqrt2 + mod, n) + mod) % mod << endl;
	return 0;
} 
posted @ 2021-01-17 22:56  zhoukangyang  阅读(161)  评论(0编辑  收藏  举报