2019 南昌网络赛 H. The Nth Item(齐次线性递推 + 快速幂分块打表)

在这里插入图片描述


这是二阶齐次递推式,一个做法是构造二阶矩阵然后矩阵快速幂,复杂度为 O ( 8 ∗ q ∗ log ⁡ ( 1 0 9 ) ) O(8 * q * \log (10^9)) O(8qlog(109)),T飞。
对于齐次线性递推式,可以推导它的通项公式:
F ( n ) = x n F(n) = x^n F(n)=xn F ( n ) − 3 ∗ F ( n − 1 ) − 2 ∗ F ( n − 2 ) = 0 F(n) - 3 * F(n - 1) - 2 * F(n - 2) = 0 F(n)3F(n1)2F(n2)=0 = x n − 3 x n − 1 − 2 x n − 2 = 0 =x^n - 3 x ^{n-1} - 2x^{n-2}=0 =xn3xn12xn2=0 x 2 − 3 x + 2 = 0 x^2-3x+2=0 x23x+2=0可以解出两个特征根: x 1 = 3 + 17 2 , x 2 = 3 − 17 2 x_1 = \frac{3+\sqrt {17}}{2},x_2 = \frac{3-\sqrt {17}}{2} x1=23+17 ,x2=2317

那么 F ( n ) F(n) F(n) 的通解为: c 1 ∗ 3 + 17 2 + c 2 ∗ 3 − 17 2 c_1 * \frac{3+\sqrt {17}}{2} + c2 * \frac{3-\sqrt {17}}{2} c123+17 +c22317

c 1 ∗ x 1 + c 2 ∗ x 2 + . . + c n ∗ x n c_1 * x_1 + c_2 * x_2 + .. + c_n * x_n c1x1+c2x2+..+cnxn F ( n ) F(n) F(n)的通解仅当 x 1 , x 2 , . . . , x n x_1,x_2,...,x_n x1,x2,...,xn是 n 个不重复的特征根。

F ( 0 ) = 0 , F ( 1 ) = 1 F(0) = 0,F(1) = 1 F(0)=0,F(1)=1,带入可解出 c 1 = 17 17 , c 2 = − 17 17 c_1 = \frac{\sqrt{17}}{17},c_2 = -\frac{\sqrt{17}}{17} c1=1717 ,c2=1717

F ( n ) = 17 17 ∗ ( ( 3 + 17 2 ) n − ( 3 − 17 2 ) n ) F(n) = \frac{\sqrt{17}}{17}*((\frac{3+\sqrt {17}}{2})^n - (\frac{3-\sqrt {17}}{2})^n) F(n)=1717 ((23+17 )n(2317 )n)

17 \sqrt{17} 17 的二次同余展开为: 524399943 524399943 524399943
那么每次询问 l o g ( 1 0 9 ) log(10^9) log(109)求快速幂即可,但由于 q q q达到了 1 0 7 10^7 107,这样还不够快。

对于 ( 3 + 17 2 ) n (\frac{3+\sqrt {17}}{2})^n (23+17 )n ( 3 − 17 2 ) n (\frac{3-\sqrt {17}}{2})^n (2317 )n,可以分块打表记录,预处理 n = 1 , 2 , . . . , 1 0 9 n = 1,2,...,\sqrt{10^9} n=1,2,...,109 以及 n = 1 ∗ 1 0 9 , 2 ∗ 1 0 9 , . . . , 1 0 9 ∗ 1 0 9 n = 1 * \sqrt{10^9},2 * \sqrt{10^9},...,\sqrt{10^9}*\sqrt{10^9} n=1109 ,2109 ,...,109 109 的值,即可实现O(1)查询


代码:

#include<bits/stdc++.h>
using namespace std;
const int p = 524399943;		//sqrt(17) mod 998244353 的二次剩余 
const int mod = 998244353;
const int maxn = 1e5 + 10;
typedef long long ll;
ll fpow(ll a,ll b) {
	ll r = 1;
	while(b) {
		if(b & 1) r = r * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	return r;
} 
ll block,num;
ll mp1[maxn],np1[maxn];
ll mp2[maxn],np2[maxn];
ll inv2,invp;
ll cal(ll x) {
	x %= (mod - 1);
	ll t1 = np1[x / block] * mp1[x % block] % mod;
	ll t2 = np2[x / block] * mp2[x % block] % mod;
	return (t1 - t2 + mod) % mod * invp % mod;
}
ll n,q;
int main() {
	inv2 = fpow(2,mod - 2);
	invp = fpow(p,mod - 2);
	ll a = (3 + p) * inv2 % mod,b = (3 - p + mod) % mod * inv2 % mod;
	//分块打表,新技能
	block = sqrt(mod);
	num = mod / block + 1;
	mp1[0] = mp2[0] = 1;
	for(int i = 1; i <= block; i++) {
		mp1[i] = mp1[i - 1] * a % mod;
		mp2[i] = mp2[i - 1] * b % mod;
	}
	np1[0] = np2[0] = 1;
	for(int i = 1; i <= num; i++) {
		np1[i] = np1[i - 1] * mp1[block]  % mod;
		np2[i] = np2[i - 1] * mp2[block]  % mod;
	}
	ll ans = 0,res = 0;
	scanf("%lld%lld",&q,&n);
	while(q--) {
		n = n ^ (ans * ans);
		ans = cal(n);
		res ^= ans;
	}
	printf("%lld\n",res);
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
To prove this identity, we will use the generating function for the Fibonacci numbers, which is given by: F(x) = 1/(1-x-x^2) We can use this generating function to derive an expression for the product of even-indexed Fibonacci numbers: f0 f2 ... f2n = F(x^2) = 1/(1-x^2-x^4)...(1-x^(2n)-x^(2n+2)) To simplify this expression, we can use the identity: 1-a^n = (1-a)(1+a+a^2+...+a^(n-1)) Using this identity, we can write: 1-x^(2n+2) = (1-x^2)(1+x^2+x^4+...+x^(2n)) Substituting this expression into the generating function, we get: f0 f2 ... f2n = 1/(1-x^2-x^4)...(1-x^(2n)(1-x^2)(1+x^2+x^4+...+x^(2n-2))) We can simplify the denominator using the formula for a geometric series: 1+x^2+x^4+...+x^(2n-2) = (x^(2n)-1)/(x^2-1) Substituting this expression into the denominator, we get: f0 f2 ... f2n = 1/(1-x^2-x^4)...(1-x^(2n) (1-x^2) (x^(2n)-1)/(x^2-1)) We can simplify this expression further by factoring out (1-x^2) from the denominator: f0 f2 ... f2n = (1-x^2)^n / (1-x^2-x^4)...(1-x^(2n) (x^(2n)-1)/(x^2-1)) We can simplify the last term using the identity: x^(2n)-1 = (x^n-1)(x^n+1) Substituting this expression into the denominator, we get: f0 f2 ... f2n = (1-x^2)^n / (1-x^2-x^4)...(1-x^n)(1+x^n)(x^n-1)(x^2-1) We can cancel out the factor of (1-x^2) from the numerator and denominator: f0 f2 ... f2n = (1-x^2)^(n-1) / (1-x^4-x^8)...(1-x^n)(1+x^n)(x^n-1)(x^2-1) Using the identity: 1-x^4-x^8-...-x^(4n) = (1-x^2)(1+x^2+x^4+...+x^(2n)) We can simplify the denominator further: f0 f2 ... f2n = (1-x^2)^(n-1) / ((1-x^2)(1+x^2+x^4+...+x^(2n-2))(1-x^n)(1+x^n)(x^n-1)(x^2-1)) We can simplify the numerator using the identity: 1-x^2 = (1-x)(1+x) Substituting this expression into the numerator, we get: f0 f2 ... f2n = (1-x)^(n-1) (1+x)^(n-1) / ((1-x)(1+x+x^2+...+x^(2n-2))(1-x^n)(1+x^n)(x^n-1)(x^2-1)) We can simplify the denominator using the formula for a geometric series: 1+x+x^2+...+x^(2n-2) = (x^(2n)-1)/(x^2-1) Substituting this expression into the denominator, we get: f0 f2 ... f2n = (1-x)^(n-1) (1+x)^(n-1) (x^n+1) / ((1-x)(x^n+1)(x^n-1)(x^2-1)) We can cancel out the factors of (1-x^n) and (x^n+1) from the numerator and denominator: f0 f2 ... f2n = (1-x)^(n-1) (1+x)^(n-1) / ((1-x)(x^n-1)(x^2-1)) Finally, we can use the identity: 1-x^n = (1-x)(1+x+x^2+...+x^(n-1)) Substituting this expression into the denominator, we get: f0 f2 ... f2n = (1-x)^(n-1) (1+x)^(n-1) / ((1-x)^2(1+x+x^2+...+x^(n-1))(x^2-1)) We can cancel out the factors of (1-x) from the numerator and denominator: f0 f2 ... f2n = (1+x)^(n-1) / ((1+x+x^2+...+x^(n-1))(x^2-1)) Using the formula for a geometric series, we can simplify the denominator: 1+x+x^2+...+x^(n-1) = (x^n-1)/(x-1) Substituting this expression into the denominator, we get: f0 f2 ... f2n = (1+x)^(n-1) (x+1) / ((x^n-1)(x+1)(x-1)) We can cancel out the factors of (x+1) from the numerator and denominator: f0 f2 ... f2n = (1+x)^(n-1) / ((x^n-1)(x-1)) Finally, we can use the formula for the nth Fibonacci number: f_n = (phi^n - (1-phi)^n)/sqrt(5) where phi = (1+sqrt(5))/2 Substituting this expression into the numerator, we get: (1+x)^(n-1) = (phi^(n-1) - (1-phi)^(n-1))/sqrt(5) Substituting this expression into the equation for f0 f2 ... f2n, we get: f0 f2 ... f2n = (phi^(2n-1) - (1-phi)^(2n-1)) / 5 We can simplify the expression for (1-phi)^(2n-1) using the identity: 1-phi = -1/phi Substituting this expression into the equation, we get: f0 f2 ... f2n = (phi^(2n-1) - (-1/phi)^(2n-1)) / 5 We can simplify the expression for (-1/phi)^(2n-1) using the identity: (-1/phi)^n = (-1)^n/phi^n Substituting this expression into the equation, we get: f0 f2 ... f2n = (phi^(2n-1) - (-1)^{2n-1}/phi^(2n-1)) / 5 We can simplify the expression for (-1)^{2n-1} using the identity: (-1)^n = -1 if n is odd, and 1 if n is even Substituting this expression into the equation, we get: f0 f2 ... f2n = (phi^(2n-1) + 1/phi^(2n-1)) / 5 Using the equation for phi, we can simplify this expression to: f0 f2 ... f2n = (F(2n+1) + (-1)^n)/2 where F(n) is the nth Fibonacci number. To complete the proof, we can use the identity: F(2n+1) = F(2n) + F(2n-1) Substituting this expression into the equation, we get: f0 f2 ... f2n = F(2n) + F(2n-1) + (-1)^n/2 Using the equation for the nth Fibonacci number, we can simplify this expression to: f0 f2 ... f2n = F(2n+1) - 1/2 + (-1)^n/2 Using the identity F(2n+1) = F(2n) + F(2n-1) again, we get: f0 f2 ... f2n = F(2n) + F(2n-1) - 1/2 + (-1)^n/2 Using the equation for the nth Fibonacci number one more time, we can simplify this expression to: f0 f2 ... f2n = F(2n+1) - 1/2 + (-1)^n/2 This completes the proof of the identity f0 f2 ... f2n = F(2n+1) - 1/2 + (-1)^n/2.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值