u's的影响力 (矩阵构造)(第五次重新来过)

我昨天写这个题,写道凌晨两点,一直81分,直到刚才,我发现了错误的地方,一改就A了,woc,心态崩了

μ’s在九人齐心协力下,影响力越来越大了!
已知第一天影响力为 x x x ,第二天影响力为 y y y ,从第三天开始,每一天的影响力为前两天影响力的乘积再乘以 a a a b b b 次方。 用数学语言描述是:

设第 i i i天的影响力为 f ( i ) f(i) f(i),那么 f ( 1 ) = x f(1)=x f(1)=x f ( 2 ) = y f(2)=y f(2)=y,对于 i > 2 , f ( i ) = f ( i − 1 ) ∗ f ( i − 2 ) ∗ a b i>2,f(i)=f(i-1)*f(i-2)*a^b i>2,f(i)=f(i1)f(i2)ab, 她们想知道第 n n n天影响力是多少?

由于这个数可能非常大,只需要输出其对 1000000007 1000000007 1000000007 取模的值就可以了。

输入:一行五个正整数: n , x , y , a , b n,x,y,a,b n,x,y,a,b ( 1 ≤ n , x , y , a , b ≤ 1 0 12 ) (1\leq n,x,y,a,b\leq 10^{12}) (1n,x,y,a,b1012)

输出:第 n n n天的影响力对 1000000007 1000000007 1000000007 取模的值。

x x x y y y 的幂次是叠加的,因为是幂的乘积嘛,而且是 f ( i ) = f ( i − 1 ) ∗ f ( i − 2 ) f(i)=f(i-1)*f(i-2) f(i)=f(i1)f(i2),可以发现,指数其实就是 g ( i ) = g ( i − 1 ) + g ( i − 2 ) g(i)=g(i-1)+g(i-2) g(i)=g(i1)+g(i2),其实就是Fib了,求斐波那契数列, x x x y y y 指数就得到了解决。而对于 a a a 的指数,可以明了 b b b 是不变的,所以只有 b b b 前面的系数在变化,而 b b b 前面的系数是当前项 x x x y y y 的系数之和 − 1 -1 1,因此 b b b 的系数也得到了解决。

因为数据量很大,所以不能通过递推求Fib,可以通过矩阵快速幂求解Fib,但是Fib很大,需要取模,而Fib又在指数位置上,根据费马小定理(或者欧拉降幂公式),让Fib对( 1 0 9 + 7 − 1 10^9+7-1 109+71)取模即可。

注意 n = 1 ∣ ∣ n = 2 n=1||n=2 n=1n=2的时候直接输出 x ∣ ∣ y x||y xy但是,因为 x ∣ ∣ y x||y xy的值都很大,答案需要对 1 0 9 + 7 10^9 +7 109+7取模。(我就这个地方wa了好多好多遍)

#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof a)
const int mod = 1e9 + 7;
typedef long long ll;
ll qc(ll x,ll y,ll m)
{
    
    
    return (x*y-(ll)((long double)x/m*y)*m+m)%m;
}
ll qpow(ll x, ll y, ll m){
    
    
	ll res = 1;
	res %= m;
	while (y){
    
    
		if(y & 1){
    
    
			res = qc(res, x, m);
		}
		y >>= 1;
		x = qc(x, x, m);
	}
	return res % m;
}
struct p{
    
    
	ll a[3][3];
	p(){
    
    
		mem(a, 0);
	}
	void clear(){
    
    
		p();
	}
	p(ll b[3][3]){
    
    
		clear();
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				a[i][j] = b[i][j];
	}
	p operator * (const p& temp){
    
    
		p ans;
		ans.clear();
		for (int i = 1; i <= 2; i++){
    
    
			for (int j = 1; j <= 2; j++){
    
    
				for (int k = 1; k <= 2; k++){
    
    
					ans.a[i][j] += qc(this->a[i][k], temp.a[k][j], mod - 1);
					ans.a[i][j] %= (mod - 1);
				}
			}
		}
		return ans;
	}
};
p qpow(p t, ll n){
    
    
	p res;
	res.clear();
	res.a[1][1] = 1;
	res.a[2][2] = 1;
	while (n){
    
    
		if (n & 1){
    
    
			res = res * t;
		}
		n >>= 1;
		t = t * t;
	}
	return res;
}
ll n, x, y, a, b;
int main()
{
    
    
	while(~scanf("%lld %lld %lld %lld %lld", &n, &x, &y, &a, &b)){
    
    
		ll fib1, fib2;
		p temp;
		temp.clear();
		temp.a[1][2] = temp.a[2][1] = temp.a[2][2] = 1;
		if (n == 1){
    
    
			printf("%lld\n", x % mod);
		}
		else if (n == 2){
    
    
			printf("%lld\n", y % mod);
		}
		else {
    
    
			p ans = qpow(temp, n - 2);
			fib1 = ans.a[2][1];
			fib2 = ans.a[2][2];
			ll z = fib1 + fib2 - 1;
			ll res = qpow(x, fib1 % (mod - 1), mod);
			res = qc(res, qpow(y, fib2 % (mod - 1), mod), mod);
			a = qpow(a, b, mod);
			res = qc(res, qpow(a, z, mod), mod); 
			res %= mod;
			if (x % mod == 0 || y % mod == 0 || a % mod == 0){
    
    
				res = 0;
			}
			printf("%lld\n", res);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43701790/article/details/105451220
今日推荐