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.
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 .
Output
Output one number for each case,which is
fn mod p.
Sample Input
Sample Output
Source
BestCoder Round #80
题目大意:
官方题解:
个人的解题思路:
首先对这个题进行分析一下,我们发现这个f(n)的每一项都有一个底数 a ,所以 我们就对 a 进行取对数,令
g(n)=logaf(n)
即得到一个递推式:
g(n)=logaab+logaf(n−1)c+logaf(n−2)
即
g(n)=c∗g(n−1)+g(n−2)+b
所以可以构造矩阵 A 满足
{g(n−1),g(n−2),b}∗A=={g(n),g(n−1),b}
又因为
f(n)=ab∗f(n−1)c∗f(n−2)
所以
g(n)=logaf(n)=b+c∗g(n−1)+g(n−2)
所以构造的矩阵 A 为:
c11100001
所以 我们可就知道了g(n)的值是多少,当 n=3的时候
因为:
{g(2),g(1),b}∗A3−2=={g(3),g(3−1),b}
所以:
{g(2),g(1),b}∗An−2=={g(n),g(n−1),b}
所以我们只要求吃构造矩阵的的 (n-2)次方来就行了,注意的是取模的时候是对 phi(p)取模因为我们要求的结果是
f(n)=ag(n)
因为
ab%mod=ab%phi(mod)+phi(mod)%mod
又因为 p 是质数,所以 phi(p) = p-1;
这里我们要用到的就是 矩阵的乘法 和 矩阵的快速幂 + 普通的快速幂就行了。
My Code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int MAXN = 3;
typedef long long LL;
typedef struct
{
LL mat[MAXN][MAXN];
} Matrix;
LL c;
///求得的矩阵
Matrix p = {c, 1, 0,
1, 0, 0,
1, 0, 1,
};
///单位矩阵
Matrix I = {1, 0, 0,
0, 1, 0,
0, 0, 1,
};
///矩阵乘法
Matrix Mul_Matrix(Matrix a, Matrix b, LL MOD)
{
Matrix c;
for(int i=0; i<MAXN; i++)
{
for(int j=0; j<MAXN; j++)
{
c.mat[i][j] = 0;
for(int k=0; k<MAXN; k++)
{
c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % MOD;
c.mat[i][j] %= MOD;
}
}
}
return c;
}
///矩阵的快速幂
Matrix quick_Mod_Matrix(LL m, LL MOD)
{
Matrix ans = I, b = p;
while(m)
{
if(m & 1)
ans = Mul_Matrix(ans, b, MOD);
m>>=1;
b = Mul_Matrix(b, b, MOD);
}
return ans;
}
///普通的快速幂
LL quick_Mod(LL a, LL b, LL MOD)
{
LL ans = 1;
while(b)
{
if(b & 1)
ans = (ans * a) % MOD;
b>>=1;
a = (a * a) % MOD;
}
return ans;
}
int main()
{
int T;
LL n, a, b, MOD;
scanf("%d",&T);
while(T--)
{
cin>>n>>a>>b>>c>>MOD;
p.mat[0][0] = c;
if(n == 1)
{
puts("1");
continue;
}
if(n == 2)
{
LL ret = quick_Mod(a, b, MOD);
cout<<ret<<endl;
continue;
}
Matrix tmp = quick_Mod_Matrix(n-2, MOD-1);///注意取模是MOD-1
LL ans = ( b * tmp.mat[0][0] ) % ( MOD-1 ) + ( b * tmp.mat[2][0] ) % ( MOD-1 );
LL ret = quick_Mod(a, ans, MOD);///a^b%MOD
cout<<ret<<endl;
}
return 0;
}
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.
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 .
Output
Output one number for each case,which is
fn mod p.
Sample Input
Sample Output
Source
BestCoder Round #80