64位整数乘法解析(以及一些疑惑)

题目描述

求 a 乘 b 对 p 取模的值,其中 1≤a,b,p≤10^18

链接:https://ac.nowcoder.com/acm/contest/996/C

来源:牛客网


代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    long long a,b,p,ans=0,n=1;cin>>a>>b>>p;a%=p;b%=p;
    while(b){
        if(b&1){
            ans=(ans+a)%p;
        }
        a=a*2%p;
        b>>=1;
    }
    cout<<ans;
    return 0;
}
  1. 先对a,b取余。a%=p;b%=p;

  1. 将b看成二进制数。以b=13为例,二进制数为1101,则a*b变成了

a*(1+4+8)=1*a+4*a+8*a

所以我们可以把题目视作:

将b看成二进制数后,对b的每一位进行检查,如果第i位为1,就把其对应的2^i与a相乘,加入ans中。

循环i次,则a*(2^i)=a' *2, a'为前一个循环中的a。每次循环,a都乘一个2进来。

令我困惑的是,这样写代码就过不了:

#include<bits/stdc++.h>
using namespace std;
int main(){
    long long a,b,p,ans=0;cin>>a>>b>>p;a%=p;b%=p;
    long long n=1;
    while(b){
        if(b&1){
            ans=(ans+(a*n)%p)%p;
        }
        n*=2;
        b>>=1;
    }
    cout<<ans;
    return 0;
}

下面是正确的代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    long long a,b,p,ans=0,n=1;cin>>a>>b>>p;a%=p;b%=p;
    while(b){
        if(b&1){
            ans=(ans+a)%p;
        }
        a=a*2%p;
        b>>=1;
    }
    cout<<ans;
    return 0;
}

我将报错的写法和正确的写法做了个融合,也过不了。大家可以对比一下下面这个代码注释部分与打问号的部分有什么不同。自己试了很多样例,都是一样的,但就是不能过。

#include<bits/stdc++.h>
using namespace std;
int main(){
    long long a,b,p,ans=0,n=1;cin>>a>>b>>p;a%=p;b%=p;
    while(b){
        if(b&1){
            ans=(ans+a)%p;
        }
        //a=a*2%p;
        n*=2;//?
        a=a*n;//?
        a=a%p;//?
        b>>=1;
    }
    cout<<ans;
    return 0;
}

不知道大家是否也有类似的困惑。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值