NKOJ 9602

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; 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值