• 【题解】Acwing 90 64位整数乘法


    64位整数乘法

    题目传送门

    求 a 乘 b 对 p 取模的值。
    

    输入格式

    第一行输入整数a,第二行输入整数b,第三行输入整数p。
    

    输出格式

    输出一个整数,表示a*b mod p的值。
    

    数据范围

    1≤a,b,p≤1018
    

    输入样例:

    3
    4
    5
    

    输出样例:

    2
    

    思路说明:

    解法一:

    类快速幂写法。
    可以参看a ^ b的思路说明

    代码展示:

    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;typedef unsigned long long ull;
    
    ll a,b,p;
    ll mul(ll a,ll b,ll p){
        ll ans = 0,ttt = a;
        while(b>0){
            if(b&1) ans = (ans+ttt) % p;
            ttt = (ttt<<1) % p;
            b >>= 1;
        }
        return ans;
    }
    
    int main(){
        scanf("%lld%lld%lld", &a, &b, &p);
        printf("%lld
    ", mul(a,b,p));
        return 0;
    }
    

    解法二:

    思路说明:

    主要利用

    a * b mod p = a * b - (lfloor)a * b / p( floor) * p

    当M大于a * b时,a * b % p = a * b % M % p

    这里的强制转化就是这样一个对一个大数取模的过程。

    注意考虑浮点数的精度误差。

    书上有些地方使用ull,在题目指定范围内,ll应当也是能达到同样效果

    一些细节将会在代码的注释中说明。

    时间复杂度 O(1)

    代码展示:

    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;typedef unsigned long long ull;
    typedef long double ld;
    
    ll a,b,p;
    
    ll mul(ll a,ll b,ll p){
        a %= p, b %= p; // 确保 a 和 b 在0 ~ p之间
    	ll c = (ld)a * b / p; 
    	ll x = a * b, y = c * p;
    	ll ans = (ll)(x % p) - (ll)(y % p);
    	if(ans < 0) ans += p; // 强制转化可能使c变小了
    	return ans;
    }
    
    int main(){
        scanf("%lld%lld%lld", &a, &b, &p);
        printf("%lld
    ", mul(a,b,p));
        return 0;
    }
    
  • 相关阅读:
    netstat 命令查看本机网络连接情况
    代替readonly
    Windows 性能监视器工具perfmon
    IE地址栏显示网站图标
    git log
    git 远程仓库管理
    git branch
    linux 安装p7zip 支持rar
    git使用教程(二) 基础
    centos 安装chrome
  • 原文地址:https://www.cnblogs.com/RemnantDreammm/p/14126216.html
Copyright © 2020-2023  润新知