矩阵乘法的快速幂和乘法的快速幂
其中做了点优化,用该矩阵可由 f0,f1 --> f2,f3 减少计算次数,如果数据量再大点应该看得出来效果
最关键的是在矩阵乘法中的取模运算要选 MOD-1,在这被坑的很惨
#include<stdio.h>
#include <string.h>
typedef __int64 ll;
const ll MOD = 1000000007;
struct matrix
{
ll f11, f12, f21, f22;
matrix() {f11 = f12 = f21 = 1; f22 = 2; }
matrix operator *(matrix &a) const
{
matrix tp;
tp.f11 = a.f11*f11 + a.f12*f21;
tp.f11 %= MOD-1;
tp.f12 = a.f11*f12 + a.f12*f22;
tp.f12 %= MOD-1;
tp.f21 = a.f21*f11+a.f22*f21;
tp.f21 %= MOD-1;
tp.f22 = a.f21*f12+a.f22*f22;
tp.f22 %= MOD-1;
return tp;
}
};
ll getres(ll nm, ll c)
{
ll res = 1, tp = nm;
while (c)
{
if (c & 0x1) res *= tp;
res %= MOD;
tp *= tp;
tp %= MOD;
c>>= 1;
}
return res;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int n;
ll a, b;
while (scanf("%I64d%I64d%d", &a, &b, &n) != EOF)
{
if (!n) printf("%I64d\n", a);
else if ( n == 1) printf("%I64d\n", b);
else if (!a || !b) printf("0\n");
else
{
matrix res, tp ,c;
int tm = n/2-1;
ll cot = 1;
while (tm)
{
if (tm & 0x1) res = res*tp;
tp = tp*tp;
tm >>= 1;
}
// a
ll a1 = res.f11, a2 = res.f21;
// b
ll b1 = res.f12, b2 = res.f22;
if ( n & 0x1)
{
cot = getres(a, a2)*getres(b, b2);
cot %= MOD;
}
else
{
cot = getres(a, a1)*getres(b, b1);
cot %= MOD;
}
printf("%I64d\n", cot);
}
}
return 0;
}