hnu10388 高级模运算

高级模运算

Problem Description

人与人是不同的,有些人喜欢阅读满是女孩子的杂志,有些人喜欢在地下室引爆炸弹,而还有一些却喜欢一些麻烦的数字游戏。比如ESSE论坛的一次活动:

每个人选择两个数字AiBi写在纸上,其他人不能看见。过了一段时间后,每个人说出自己纸上的数字,然后每个人的目标是求出所有的AiBi的和模M的值,最先算出结果的,就是胜利者。

作为一个程序员,你当然有办法编一个程序,以最快的速度算出结果,赢得比赛。

Input

输入包含Z组测试数据,输入第一行只包含数字Z。随后是测试数据:第一行是一个数字M(1≤M≤45000)。第二行是数字H1≤H≤45000)表示参加游戏的人数。接下来H行,每行两个数AiBi1≤AiBi≤231)。

Output

对于每组测试数据,输出以下表达式的值:

(A1B1+A2B2+...+AHBH)mod M.

Sample Input

2

16

4

2 3

3 4

4 5

5 6

36123

1

23748593029382

Sample Output

2

13195

 

思路:

将b以二进制存在数组中,再利用公式:

ab=a2^b0+2^b1+…+2^bk=a2^b0×a2^b1×a2^bk

其中因子递推,后项因子为前项的平方;

本题关键在于:

为防止中间结果过大溢出,应不断取模

 

#include<stdio.h>
long a[45004],b[45004];
int idx[34],am[34];
int abm(long a,long b,int m)
{
    int i=0,j,k,p=1;
    while(b)
    {
        idx[i++]=b%2;
        b>>=1;
    }
    am[0]=a%m;
    for(j=1; j<i; j++)
        am[j]=am[j-1]*am[j-1]%m;
    for(k=0; k<i; k++)
    {
        if(idx[k])
            p=p*am[k]%m;
    }
    return p;
}
int main()
{
    int z,m,h,i,s;
    scanf("%d",&z);
    while(z--)
    {
        scanf("%d%d",&m,&h);
        for(i=0; i<h; i++)
            scanf("%ld%ld",&a[i],&b[i]);
        s=0;
        for(i=0; i<h; i++)
            s=(s+abm(a[i],b[i],m))%m;
        printf("%d\n",s);
    }
    return 0;
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值