矩阵快速幂:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn = 3*1e6+5;
struct Matrix{
long long an[2][2];
};
LL a, b, x0, x1;
char n[maxn];
LL mod;
Matrix Multi(Matrix A, Matrix B){
Matrix C;
C.an[0][0] = C.an[0][1] = C.an[1][0] = C.an[1][1] = 0;
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 2; k++)
C.an[i][j] = (C.an[i][j] + A.an[i][k] * B.an[k][j]) % mod;
return C;
}
//二进制快速幂
Matrix quick_mod2(Matrix A, long long n){
Matrix B;
B.an[0][0] = B.an[1][1] = 1;
B.an[0][1] = B.an[1][0] = 0;
while(n){
if(n&1) B = Multi(B, A);
A = Multi(A, A);
n >>= 1;
}
return B;
}
//十进制快速幂
Matrix quick_mod10(Matrix A, char s[]){
Matrix B, t = A;
B.an[0][0] = B.an[1][1] = 1;
B.an[0][1] = B.an[1][0] = 0;
int len = strlen(s);
len--;
while(len >= 0){
LL num = s[len] - '0';
Matrix cur = t;
for(int i = 1; i <= num; i++)
B = Multi(B, t);
for(int i = 1; i < 10; i++)
cur = Multi(cur, t);
t = cur;
len--;
}
return B;
}
int main()
{
scanf("%lld%lld%lld%lld", &x0, &x1, &a, &b);
scanf("%s", n);
scanf("%lld", &mod);
int len = strlen(n);
Matrix A, ans;
A.an[0][0] = a; A.an[0][1] = b;
A.an[1][0] = 1; A.an[1][1] = 0;
ans = quick_mod10(A, n);
// printf("%lld %lld\n", ans.an[0][0], ans.an[0][1]);
printf("%lld\n", (ans.an[1][0]*x1 + ans.an[1][1]*x0) % mod);
}
题目:牛客多校第五场 https://ac.nowcoder.com/acm/contest/885/B
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn = 3*1e6+5;
struct Matrix{
long long an[2][2];
};
LL a, b, x0, x1;
char n[maxn];
LL mod;
Matrix Multi(Matrix A, Matrix B){
Matrix C;
C.an[0][0] = C.an[0][1] = C.an[1][0] = C.an[1][1] = 0;
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 2; k++)
C.an[i][j] = (C.an[i][j] + A.an[i][k] * B.an[k][j]) % mod;
return C;
}
Matrix quick_mod(Matrix A, long long n){
Matrix B;
B.an[0][0] = B.an[1][1] = 1;
B.an[0][1] = B.an[1][0] = 0;
while(n){
if(n&1) B = Multi(B, A);
A = Multi(A, A);
n >>= 1;
}
return B;
}
//十进制快速幂
Matrix quick_mod10(Matrix A, char s[]){
Matrix B, t = A;
B.an[0][0] = B.an[1][1] = 1;
B.an[0][1] = B.an[1][0] = 0;
int len = strlen(s);
len--;
// LL num = s[len] - '0' - 1;
// Matrix cur = t;
// for(int i = 1; i <= num; i++)
// B = Multi(B, t);
// for(int i = 1; i < 10; i++)
// cur = Multi(cur, t);
// t = cur;
// len--;
while(len >= 0){
LL num = s[len] - '0';
Matrix cur = t;
for(int i = 1; i <= num; i++)
B = Multi(B, t);
for(int i = 1; i < 10; i++)
cur = Multi(cur, t);
t = cur;
len--;
}
return B;
}
int main()
{
scanf("%lld%lld%lld%lld", &x0, &x1, &a, &b);
scanf("%s", n);
scanf("%lld", &mod);
int len = strlen(n);
Matrix A, ans;
A.an[0][0] = a; A.an[0][1] = b;
A.an[1][0] = 1; A.an[1][1] = 0;
// int k = 0;
// for(int i = len-1;i >= 0;--i)
// {
// if(n[i] != '0'){
// k = i;
// break;
// }
// }
// n[k] -= 1;
// for(int i = len-1;i > k;--i)
// n[i] = '9';
ans = quick_mod10(A, n);
// printf("%lld %lld\n", ans.an[0][0], ans.an[0][1]);
printf("%lld\n", (ans.an[1][0]*x1 + ans.an[1][1]*x0) % mod);
}
普通二进制快速幂、十进制快速幂
//二进制快速幂
LL quick_mod2(LL x, LL n, LL mod) //x ^ n
{
LL res = 1;
while(n){
if(n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
//十进制快速幂
LL quick_mod10(LL x, char s[], LL mod){
LL res = 1, t = x;
int len = strlen(s); len--;
while(len >= 0){
int num = s[i] - '0', cur = t;
for(int i = 1; i <= num; i++)
ans = ans * t % mod;
for(int i = 1; i < 10; i++)
cur = cur * t % mod;
t = cur;
len--;
}
return res;
}