![](https://img-blog.csdnimg.cn/img_convert/caff8289663bcbbdaa15a975f725dff7.png)
1.
aaaaaa可以表示为111111 * a
= 999999 / 9 * a
= (1000000 - 1) / 9 * a
1000000可以用快速幂算,但是对什么取模, c不一定与这个互质
推出 (a / b) % c == (a % bc) / c (a 整除 b), 就可以做了
#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int maxn = 1e5 + 2;
ll a, b, c;
inline ll qpls(ll a, ll b) {
ll ans = 0;
ll tp = a;
while(b > 0) {
if(b & 1) {
ans += tp;
ans %= (9 * c);
}
tp += tp;
tp %= (9 * c);
b >>= 1;
}
return ans % (9 * c);
}
inline ll qpow(ll a, ll b) {
ll ans = 1;
ll tp = a;
while(b > 0) {
if(b & 1) {
ans = qpls(ans, tp);
}
tp = qpls(tp, tp);
b >>= 1;
}
return ans;
}
inline ll read() {
ll sum = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
sum = (sum << 3) + (sum << 1) + (c ^ 48);
c = getchar();
}
return f * sum;
}
signed main() {
a = read(), b = read(), c = read();
ll op1 = qpow(10, b);
ll op2 = ((op1 - 1 + 9 * c) % (9 * c) / 9 + c) * a % c;
printf("%lld", op2);
return 0;
}
2.
递推 + 矩阵快速幂
s1 = s0 * 10 + a
#include <bits/stdc++.h>
#define int long long
#define re register
using namespace std;
const int maxn = 4;
int a, b, c;
struct node {
int a[maxn][maxn];
}op, tp;
inline int pls(int a, int b) {
int ans = 0;
int tp = a;
while(b) {
if(b & 1) {
ans += tp;
ans %= c;
}
tp += tp;
tp %= c;
b >>= 1;
}
return ans;
}
node operator * (const node &x, const node &y) {
node tp;
memset(tp.a, 0, sizeof(tp.a));
for(re int k = 1; k <= 2; ++ k) {
for(re int i = 1; i <= 2; ++ i) {
for(re int j = 1; j <= 2; ++ j) {
tp.a[i][j] = (tp.a[i][j] + pls(x.a[i][k], y.a[k][j])) % c;
}
}
}
return tp;
}
inline int read() {
int sum = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
sum = (sum << 3) + (sum << 1) + (c ^ 48);
c = getchar();
}
return f * sum;
}
signed main() {
a = read(), b = read(), c = read();
memset(op.a, 0, sizeof(op.a));
op.a[1][1] = a;
op.a[2][1] = a;
memset(tp.a, 0, sizeof(tp.a));
tp.a[1][1] = 10;
tp.a[1][2] = 1;
tp.a[2][2] = 1;
b -= 1;
while(b) {
if(b & 1) {
op = tp * op;
}
tp = tp * tp;
b >>= 1;
}
printf("%lld", op.a[1][1]);
return 0;
}
3.
万能的二分
类似快速幂
if(b & 1) s[n] = (s[n / 2] * 10 ^ (n / 2) + s[n / 2]) * 10 + a
else s[n] = s[n / 2] * 10 ^ (n / 2) + s[n / 2] // 递归版
代码是循环版
#include <bits/stdc++.h>
#define int long long
#define re register
using namespace std;
int a, b, c;
inline int mod(int x, int y) {
int op = x * y - (long long)((long double)x * y / c + 1e-8) * c;
if(op < 0) return op + c;
return op;
}
inline int qpow(int a, int b) {
int A = a;
int ans = 0;
int tp = 10;
while(b) {
if(b & 1) {
ans = (mod(ans, tp) + A) % c;
}
A = (mod(A, tp) + A) % c;
tp = mod(tp, tp);
b >>= 1;
}
return ans;
}
signed main() {
scanf("%lld%lld%lld", &a, &b, &c);
int ans = qpow(a, b);
printf("%lld", ans);
return 0;
}