题目链接:hdoj 5667 Sequence
Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1030 Accepted Submission(s): 338
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
1
5 3 3 3 233
Sample Output
190
f[i] = 0, i = 1
f[i] = a^b, i = 2
f[i] = a^b * f[i-1]^c * f[i-2], i = 3
对a取log,
g[i] = b + c * g[i-1] + g[i-2]。
发现a^g[i] = f[i] (%p)由费马小定理-> a^(g[i]%(p-1)) = f[i] (%p)。
特判a % p == 0的情况。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
#include <cmath>
#include <queue>
#include <stack>
#define ll o<<1
#define rr o<<1|1
#define CLR(a, b) memset(a, (b), sizeof(a))
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e3 + 10;
LL p;
void add(LL &x, LL y) { x += y; x %= (p-1); }
struct Ma {
LL a[3][3];
};
Ma multi(Ma x, Ma y) {
Ma z; CLR(z.a, 0);
for(int i = 0; i < 3; i++) {
for(int k = 0; k < 3; k++) {
if(x.a[i][k] == 0) continue;
for(int j = 0; j < 3; j++) {
add(z.a[i][j], x.a[i][k]*y.a[k][j]%(p-1));
}
}
}
return z;
}
Ma Solve(LL n, Ma x) {
Ma y; CLR(y.a, 0);
for(int i = 0; i < 3; i++) {
y.a[i][i] = 1;
}
while(n > 0) {
if(n & 1LL) {
y = multi(x, y);
}
x = multi(x, x);
n >>= 1;
}
return y;
}
LL pow_mod(LL a, LL n) {
LL ans = 1LL;
while(n) {
if(n & 1LL) {
ans = ans * a % p;
}
a = a * a % p;
n >>= 1LL;
}
return ans;
}
int main()
{
int t; scanf("%d", &t);
while(t--) {
LL a, b, c, n;
scanf("%lld%lld%lld%lld%lld", &n, &a, &b, &c, &p);
if(a % p == 0) {
printf("0\n");
continue;
}
if(n == 1) {
printf("1\n");
continue;
}
Ma ori, res; CLR(ori.a, 0);
ori.a[0][1] = ori.a[1][0] = ori.a[2][1] = ori.a[2][2] = 1;; ori.a[1][1] = c;
res = Solve(n-2, ori);
LL f[3], g[3]; f[0] = 0; f[1] = f[2] = b;
for(int i = 0; i < 3; i++) {
g[i] = 0;
for(int j = 0; j < 3; j++) {
add(g[i], f[j] * res.a[j][i] % (p-1));
}
}
//cout << g[1] << endl;
printf("%lld\n", pow_mod(a%p, g[1]));
}
return 0;
}