NC23046 华华教月月做数学

题目

题目描述

找到了心仪的小姐姐月月后,华华很高兴的和她聊着天。然而月月的作业很多,不能继续陪华华聊天了。华华为了尽快和月月继续聊天,就提出帮她做一部分作业。
月月的其中一项作业是:给定正整数 \(A\)\(B\)\(P\) ,求 \(A^B\mod P\) 的值。华华觉得这实在是毫无意义,所以决定写一个程序来做。但是华华并不会写程序,所以这个任务就交给你了。
因为月月的作业很多,所以有T组询问。

输入描述

第一行一个正整数 \(T\) 表示测试数据组数。
接下来 \(T\) 行,每行三个正整数 \(A\)\(B\)\(P\) ,含义如上文。

输出描述

输出 \(T\) 行,每行一个非负整数表示答案。

示例1

输入

2
2 5 10
57284938291657 827493857294857 384729583748273

输出

2
18924650048745

备注

\(1\le T\le10^3\)\(1\le A,B,P\le10^{18}\)

题解

知识点:运算优化。

注意到,模数是超 \(int\) 的,乘法以后会超 \(long \ long\) 因此用龟速乘(或者 __int128_t )。

时间复杂度 \(O(logB)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>
#define ll long long

using namespace std;

ll qmul(ll a, ll b, ll p) {
    ll ans = 0;
    while (b) {
        if (b & 1) ans = (ans + a) % p;
        b >>= 1;
        a = (a << 1) % p;
    }
    return ans;
}

ll qpow(ll a, ll k, ll p) {
    ll ans = 1;
    while (k) {
        if (k & 1) ans = qmul(ans, a, p);
        k >>= 1;
        a = qmul(a, a, p);
    }
    return ans;
}

bool solve() {
    ll a, b, p;
    cin >> a >> b >> p;
    cout << qpow(a, b, p) << '\n';
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}
posted @ 2022-06-23 21:48  空白菌  阅读(98)  评论(0编辑  收藏  举报