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;
}
原文地址:https://www.cnblogs.com/AKMer/p/9698850.html