因为矩阵的运算性质,所以欧拉降幂这种骚操作是假的;
而对于a的b次方非常大时就只能用的十进制快速幂 或者 奇怪的循环节性质解决
例题:
已知数列
给定
求数列第 N 项 同时对 M 取模。
则有公式:
然后套十进制快速幂求解即可
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll MOD;
ll x0, x1, a, b, n;
struct matrix
{
ll m[2][2];
matrix()
{ m[0][0] = 1;m[1][1] = 1;m[0][1] = 0;m[1][0] = 0; }
};
matrix mul(matrix a, matrix b)
{
matrix tmp;
for(ll i = 0; i < 2; ++i)
{
for(ll j = 0; j < 2; ++j)
{
tmp.m[i][j] = 0;
for(ll k = 0; k < 2; ++k)
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
}
}
return tmp;
}
matrix qpow(matrix ra, int n)
{
matrix ans;
while(n)
{
if(n & 1)
ans = mul(ans, ra);
ra = mul(ra, ra);
n >>= 1;
}
return ans;
}
ll cal(string x)
{
matrix base, ret;
base.m[0][0] = a;
base.m[0][1] = b;
base.m[1][0] = 1;
base.m[1][1] = 0;
for(int i = x.length() - 1; i >= 0; --i) //十进制快速幂
{
int k = x[i] - '0';
if(k > 0)
ret = mul(ret, qpow(base, k));
base = qpow(base, 10);
}
ll rans = ( ( (ret.m[0][0] * x1) % MOD ) + ( (ret.m[0][1] * x0) % MOD) ) % MOD;
return rans % MOD;
}
int main()
{
string s;
cin >> x0 >> x1 >> a >> b >> s >> MOD;
int len = s.length() - 1;
while(s[len] == '0')
s[len--] = '9';
--s[len];
cout << ll( cal(s) ) << '
' ;
return 0;
}