POJ1995:Raising Modulo Numbers

Posted akmer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1995:Raising Modulo Numbers相关的知识,希望对你有一定的参考价值。

二进制前置技能:https://www.cnblogs.com/AKMer/p/9698694.html

题目传送门:http://poj.org/problem?id=1995

题目就是求(sum_{i=1}^na[i]^{b[i]}mod) (m)。我们只要会快速求(a^b)就行了。

我们可以用二进制拆分思想,把(a^b)转化成(a^{(1010...1)_2})之类的。然后根据(a^{x+y}=a^x*a^y),我们可以将(a^b)转化成(a^{(10000)_2}*a^{(100)_2}*a^{(1)_2})之类的形式。当二进制下这一位为(1),我们就把它累乘进答案里。

有因为(a^{2x}=a^x*a^x),所以对于每一位表示下(a^{(100..)_2}),我们可以通过上一位的平方得来。

所以二进制下有多少位,我们就进行多少次运算。

时间复杂度:(O(nloga))

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

代码如下:

#include <cstdio>
using namespace std;

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<‘0‘||ch>‘9‘;ch=getchar())if(ch==‘-‘)f=-1;
    for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar())x=x*10+ch-‘0‘;
    return x*f;
}

int quick(int x,int y,int m) {
    int sum=1;
    while(y) {
        if(y&1)sum=1ll*sum*x%m;//如果y的二进制当前位置为1,就把x累乘进去
        x=1ll*x*x%m;y>>=1;//否则x平方,y右移一位
    }
    return sum;
}

int main() {
    int Z=read();
    while(Z--) {
        int ans=0,m=read(),n=read();
        for(int i=1;i<=n;i++) {
            int x=read(),y=read();
            ans=(ans+quick(x,y,m))%m;//累加求答案
        }printf("%d
",ans);
    }
    return 0;
}

以上是关于POJ1995:Raising Modulo Numbers的主要内容,如果未能解决你的问题,请参考以下文章

POJ1995 Raising Modulo Numbers

poj 1995 Raising Modulo Numbers 题解

Raising Modulo Numbers(POJ 1995 快速幂)

poj1995 Raising Modulo Numbers高速幂

POJ1995 Raising Modulo Numbers(快速幂)

POJ1995:Raising Modulo Numbers