题目描述
人与人是不同的,有些人喜欢阅读满是图片的杂志,有些人喜欢在地下室引爆炸弹,而还有一些却喜欢一些麻烦的数字游戏。比如ESSE论坛的一次活动:
每个人选择两个数字Ai和Bi写在纸上,其他人不能看见。过了一段时间后,每个人说出自己纸上的数字,然后每个人的目标是求出所有的AiBi的和模M的值,最先算出结果的,就是胜利者。
输入
第一行是一个数字M (1≤M≤45000)。第二行是数字H(1≤H≤45000)表示参加游戏的人数。
接下来H行,每行两个数Ai和Bi(1≤Ai,Bi≤2^31)。
输出
输出一个数字, ( A 1 B 1 A1^{B1} A1B1 + A 2 B 2 A2^{B2} A2B2 + … + A n B n An^{Bn} AnBn) mod M 的值。
题目解析
我们需要求出每一个 A B A^{B} AB,如果直接使用for循环,时间开销会超出限制,所以应当使用快速幂去求解。
快速幂思路
如果B为偶数,则
A
B
A^{B}
AB=
A
B
/
2
A^{B/2}
AB/2
A
B
/
2
A^{B/2}
AB/2
如果B为奇数,则
A
B
A^{B}
AB=
A
B
/
2
A^{B/2}
AB/2
A
B
/
2
A^{B/2}
AB/2*A(由于C++中除法向下取整)
AC代码
#include <iostream>
using namespace std;
long long m,n,a,b;
long long MyPow(long long x,long long y,long long m)
{
if(y==0) //A^0==1
{
return 1;
}
else
{
long long ans=MyPow(x,y>>1,m);
//ans=a^(b/2),使用移位操作代替除以2,能够提升程序性能
if(!(y&1))
//二进制表示下的偶数最后一位必定为0,所以可以用按位与计算是否为偶数
{
return (ans*ans)%m;
}
else
{
return (ans*ans*x)%m;
}
}
}
int main()
{
long long res=0;
scanf("%I64d %I64d",&m,&n);
while(n--)
{
scanf("%I64d %I64d",&a,&b);
res+=(MyPow(a%m,b,m));
res%=m;
}
printf("%I64d\n",res);
return 0;
}
结果
代码AC,但是有个疑问,当我将全局变量m,n,a,b设为局部变量时,程序在OJ上运行超时,具体原因尚不清楚