Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 144 Accepted Submission(s): 46
Problem Description
Holion August will eat every thing he has found.
Now there are many foods,but he does not want to eat all of them at once,so he find a sequence.
fn=⎧⎩⎨⎪⎪1,ab,abfcn−1fn−2,n=1n=2otherwise
He gives you 5 numbers n,a,b,c,p,and he will eat fn foods.But there are only p foods,so you should tell him fn mod p.
Now there are many foods,but he does not want to eat all of them at once,so he find a sequence.
fn=⎧⎩⎨⎪⎪1,ab,abfcn−1fn−2,n=1n=2otherwise
He gives you 5 numbers n,a,b,c,p,and he will eat fn foods.But there are only p foods,so you should tell him fn mod p.
Input
The first line has a number,T,means testcase.
Each testcase has 5 numbers,including n,a,b,c,p in a line.
1≤T≤10,1≤n≤1018,1≤a,b,c≤109 , p is a prime number,and p≤109+7 .
Each testcase has 5 numbers,including n,a,b,c,p in a line.
1≤T≤10,1≤n≤1018,1≤a,b,c≤109 , p is a prime number,and p≤109+7 .
Output
Output one number for each case,which is
fn
mod p.
Sample Input
1 5 3 3 3 233
Sample Output
190
Source
BestCoder Round #80
1 0 0 【 an - 1, an - 2, 1】
思路:通过递推可以知道fn 都可以用f2 的多少次幂来表示,而幂的递推公式为an = (an - 1)* c + 1 +an - 2;因为n很大,所以用矩阵快速幂来算,
C 1 0
1 0 0 【 an - 1, an - 2, 1】
1 0 1
前面的矩阵的n - 3次幂在乘以后面的矩阵,第一个值就是答案
要注意的是 a ^ b % c = a ^(b % phi(c) + phi(c)) % c; 因为c是质数,所以这里的phi就为c - 1;所以只要用矩阵幂的时候% c -1,答案% c即可。
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cmath>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define esp 1e-8
const double PI = acos(-1.0);
const int inf = 1000000005;
//const long long mod = 1000000007;
//freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
//freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
struct Mat
{
long long mat[10][10];
}a, b, ans;
long long mod, eul;
Mat operator * (Mat a, Mat b)
{
Mat c;
memset(c.mat, 0, sizeof(c.mat));
for (int k = 0; k < 3; ++k)
{
for (int i = 0; i < 3; ++i)
{
if (a.mat[i][k] == 0)
continue;
for (int j = 0; j < 3; ++j)
{
if (b.mat[k][j] == 0)
continue;
c.mat[i][j] = (a.mat[i][k] * b.mat[k][j] % eul + c.mat[i][j]) % eul;
//c.mat[i][j] %= mod;
}
}
}
return c;
}
Mat power(Mat a, long long k)
{
Mat res = ans;
while (k)
{
if (k & 1)
res = res * a;
k >>= 1;
a = a * a;
}
return res;
}
long long n, aa, bb, cc, p;
long long power1(long long a, long long b)
{
long long res = 1;
while (b)
{
if (b & 1)
res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res % mod;
}
long long eular(long long n)
{
long long res = n, x = n;
for (long long i = 2; i * i <= n; ++i)
{
if (x % i == 0)
res = res * (i - 1) / i;
while (x % i == 0)
x /= i;
}
if (x > 1)
res = res * (x - 1) / x;
return res;
}
int main()
{
int t, i, j;
memset(ans.mat, 0, sizeof(ans));
ans.mat[0][0] = ans.mat[1][1] = ans.mat[2][2] = 1;
scanf("%d", &t);
while (t--)
{
scanf("%I64d%I64d%I64d%I64d%I64d", &n, &aa, &bb, &cc, &mod);
long long f2 = power1(aa, bb);
if (n == 1)
{
printf("1\n");
continue;
}
if (n == 2)
{
printf("%I64d\n", f2);
continue;
}
p = mod;
eul = eular(mod);
memset(a.mat, 0, sizeof(a.mat));
a.mat[0][0] = cc;
a.mat[0][1] = a.mat[1][0] = a.mat[2][0] = a.mat[2][2] = 1;
b = power(a, n - 3);
long long s = (b.mat[0][0] * (cc + 1) % eul + b.mat[1][0] * 1 % eul+ b.mat[2][0]) % eul;
printf("%I64d\n", (power1(f2, s + eul)) % mod);
}
}