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高速幂