問題蟲洞——B:generator 1
黑洞內窺:
輸入兩行,一行x0, x1, a, b, 一行n,mod。
給出一個序列的x0,x1,之後的每一項由公式: 得出,a, b也已知,,,,
求F(n)%mod;
but,,,,
你的數據非常大。。。
思維光年:
一開始是模仿斐波那契遞推公式來的,但是那個公式有限制條件,,
後來想到了矩陣快速冪,也推出了矩陣乘方,但n太™大了,,,
後來想了想,好像你先冪一個數然後再冪一個數,其實是等於冪了這兩個數的積,
比賽的時候以爲是冪了這兩個數的和,所以一直沒敢敲。。。。怕爆。。。
而正確的題解是:
ACcode:
//#include<bits/stdc++.h>
//std::ios::sync_with_stdio(false);
#include <stdio.h>
#include <iostream>
#include<algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <math.h>
#include <vector>
#include <cstring>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef long long ll;
#define MAXN 1000005
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
//const ll mod = 998244353;
#define mem(a, b) memset(a, b, sizeof(a))
char n[MAXN];
ll mod, a, b, x0, x1;
struct mat
{
ll m[4][4];
};
mat mul(mat a, mat b)
{
mat res;
for(int i=0; i<4; ++i)
for(int j=0; j<4; ++j)
res.m[i][j] = 0;
for(int i=1; i<=2; ++i)
for(int j=1; j<=2; ++j)
for(int k=1; k<=2; ++k)
res.m[i][k] = (res.m[i][k] + a.m[i][j]*b.m[j][k])%mod;
return res;
}
mat pow(mat a, int b)
{
mat ans;
memset(ans.m, 0, sizeof(ans.m));
ans.m[1][1] = ans.m[2][2] = 1;
while(b)
{
if(b&1)
ans = mul(ans, a);
a = mul(a, a);
b >>= 1;
}
return ans;
}
int main()
{
scanf("%lld %lld %lld %lld %s %lld", &x0, &x1, &a, &b, n, &mod);
int len = strlen(n);
mat ans, ori;
mem(ans.m, 0); mem(ori.m, 0);
ori.m[1][2] = 1, ori.m[2][1] = b, ori.m[2][2] = a;
ans.m[1][1] = 1, ans.m[2][2] = 1;
for(int i = len-1; i>=0; --i) //重點,以10爲單位。
{
mat t = pow(ori, n[i]-'0');
ans = mul(ans, t);
ori = pow(ori, 10);
}
cout << (x0*ans.m[1][1]+x1*ans.m[1][2])%mod << '\n';
return 0;
}