10388 高级模运算

题目描述

人与人是不同的,有些人喜欢阅读满是图片的杂志,有些人喜欢在地下室引爆炸弹,而还有一些却喜欢一些麻烦的数字游戏。比如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上运行超时,具体原因尚不清楚
运行结果截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值