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
Recommend
题目大意:
给定如题目中所述的公式,求出f(n)mod p,p是素数
解题思路:
观察公式并手写几项下来,可以发现a^b总是一起出现并且只有指数发生了变化,所以设g(n)=log f(n) (以a^b为底)
根据公式:g(n)=1+c*g(n-1)+g(n-2) mod phi(p) (n>=2) 注意是phi(p),那么就可以用矩阵快速幂:(A^表示A的转置)
(g(n),g(n-1),1)^=(c,1,1; 1,0,0; 0,0,1;)*(g(n-1),g(n-2),1)^ 根据g(1),g(2)的值算出需要的g(n)来。
之后用快速幂(a^b)^g(n) mod p可以得出f(n)
注:这种方法没有遇出题人t说的坑点
#include<stdio.h>
#include<stdio.h>
#include<iostream>
#define ll long long
#define rush() int t;scanf("%d",&t);while(t--)
using namespace std;
struct mat { ll a[3][3]; };
ll mod,mod1;
mat operator * (mat a, mat b)
{
mat ans;
memset(ans.a, 0, sizeof(ans.a));
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++)
{
ans.a[i][j] += (a.a[i][k] * b.a[k][j]) % (mod-1);
ans.a[i][j] %= mod-1;
}
return ans;
}
mat qpow(mat a, ll n)
{
mat ans;
memset(ans.a, 0, sizeof(ans.a));
for (int i = 0; i < 3; i++)ans.a[i][i] = 1;
while (n)
{
if (n & 1)ans = ans*a;
a = a*a;
n >>= 1;
}
return ans;
}
ll qpow(ll a, ll b)
{
ll ans = 1;
while (b)
{
if (b & 1)ans = (ans*a)%mod;
a =(a*a)%mod;
b >>= 1;
}
return ans;
}/*
ll phi(ll n)
{
ll temp;
temp = n;
for (int i = 2; i*i <= n; i++)
{
if (n%i == 0)
{
while (n%i == 0) n = n / i;
temp = temp / i*(i - 1);
}
if (n<i + 1)
break;
}
if (n>1)
temp = temp / n*(n - 1);
return temp;
}*/
int main()
{
rush()
{
mat tem;
ll a, b, n,c;
cin >> n >> a >> b >> c>>mod;
ll k = qpow(a, b);
if (n == 1) {cout<<'1'<<endl; continue; }
else if (n == 2) { cout << k << endl; continue; }
else
{
tem.a[0][0] = c;
tem.a[0][1] = 1;
tem.a[0][2] = 1;
tem.a[1][0] = 1;
tem.a[1][1] = 0;
tem.a[1][2] = 0;
tem.a[2][0] = 0;
tem.a[2][1] = 0;
tem.a[2][2] = 1;
tem = qpow(tem, n - 2);//不能用phi(n-2)
ll ans = ((tem.a[0][0]%(mod-1) + tem.a[0][2]%(mod-1)) % (mod-1) + mod-1) % (mod-1);
ans = qpow(k, ans);
cout << ans << endl;
}
}
}