链接:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=688&pid=1003
题意:中文题,给你f1,f2,fn=a^b+fn-1^c+fn-2,让你求fn
分析:看公式一眼矩阵快速幂,但是式子里面有fn-1^c,直接上矩阵是求不出的,我们可以观察到式子的每项都是以a为底的数,f1=a^0,f2=a^b,f3=a^(b+bc),f4=a^(b+(b+bc)*c+b);
设gx为fx的指数表达式,则gn=b+gn-1*c+gn-2,我们现在可以对g进行矩阵快速幂求出第n项的指数,然后快速幂求出最后的答案。
注意,指数取模要根据费马小定理:a^n%p与a^(n%(p-1))%p同余,所以指数的模减一。
还有数据中有a%p==0,如果不特判结果就错了。
代码:
#include <algorithm>
#include <iostream>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <set>
#include <map>
#include <ctime>
#define INF 0x3f3f3f3f
#define Mn 100010
#define Mm 200010
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul (u<<1)
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
struct Matrix {
ll mt[3][3];
Matrix() {
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
mt[i][j]=0;
}
};
Matrix Mult(Matrix b,Matrix a,ll p) {
Matrix c;
for(int i=0;i<3;i++) for(int j=0;j<3;j++) for(int k=0;k<3;k++)
(c.mt[i][j]+=a.mt[i][k]*b.mt[k][j]%p)%=p;
return c;
}
Matrix pow(Matrix a,ll n,ll p) {
Matrix re;
for(int i=0; i<3; i++) re.mt[i][i]=1;
while(n) {
if(n%2) re=Mult(re,a,p);
a=Mult(a,a,p);
n>>=1;
}
return re;
}
ll pow(ll a,ll n,ll p) {
int b=1;
while(n) {
if(n%2) b=a*b%p;
a=a*a%p;
n>>=1;
}
return b;
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
int a,b,c;
ll n,p;
Matrix init,tr;
scanf("%I64d%d%d%d%I64d",&n,&a,&b,&c,&p);
init.mt[0][0]=b;
init.mt[2][0]=b;
tr.mt[0][0]=1;
tr.mt[1][2]=1;
tr.mt[2][0]=1;
tr.mt[2][1]=1;
tr.mt[2][2]=c;
if(n==1) {
printf("1\n");
} else if(n==2) {
printf("%I64d\n",pow((ll)a,b,p));
} else {
if(a%p==0) printf("0\n");
else {
init=Mult(init,pow(tr,n-2,p-1),p-1);
printf("%I64d\n",pow((ll)a,init.mt[2][0],p));
}
}
}
return 0;
}