题目:hdu 3221 Brute-force Algorithm
题意:很简单,枚举几项就知道了
状态不好,sb了,错了好多遍
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef __int64 LL;
LL mod,p,fib[60];
struct Matrix
{
LL m[3][3];
}E,D;
void init()
{
for (int i = 1; i <= 2; i++)
{
for (int j = 1; j <= 2; j++)
{
E.m[i][j] = (i == j);
D.m[i][j] = 1;
}
}
D.m[2][2] = 0;
}
Matrix Multi(Matrix A, Matrix B)
{
Matrix ans;
for (int i = 1; i <= 2; i++)
{
for (int j = 1; j <= 2; j++)
{
ans.m[i][j] = 0;
for (int k = 1; k <= 2; k++)
ans.m[i][j] = (ans.m[i][j] + A.m[i][k] * B.m[k][j])%mod;
}
}
return ans;
}
Matrix Pow(Matrix A, LL k)
{
Matrix ans = E;
while (k)
{
if (k & 1)
{
k--;
ans = Multi(ans, A);
}
else
{
k /= 2;
A = Multi(A, A);
}
}
return ans;
}
LL euler(LL x)
{
LL i, res = x;
for (i = 2; i*i <= x; i++)
{
if (x%i == 0)
{
res = res / i*(i - 1);
while (x%i == 0)
x /= i;
}
}
if (x > 1)
res = res / x*(x - 1);
return res;
}
LL Pow(LL a, LL b)
{
LL ans = 1;
while (b)
{
if (b & 1)
{
b--;
ans = (ans*a)%p;
}
else
{
b /= 2;
a = (a*a)%p;
}
}
return ans;
}
LL Fib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
fib[0] = 0;
fib[1] = 1;
int i;
for (i = 2; i <= n; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
if (fib[i] >= mod)
break;
}
if (i > n)
return fib[n];
return Pow(D, n).m[2][1] + mod;
}
LL solve(LL a,LL b,LL n)
{
if (n == 1)
return a%p;
if (n == 2)
return b%p;
return Pow(a, Fib(n - 2))*Pow(b, Fib(n - 1))%p;
}
int main()
{
int T;
scanf("%d", &T);
for (int cas = 1; cas <= T; cas++)
{
LL a, b, n;
scanf("%I64d%I64d%I64d%I64d", &a, &b, &p, &n);
mod = euler(p);
init();
printf("Case #%d: %I64d\n", cas, solve(a, b, n));
}
return 0;
}