zoukankan      html  css  js  c++  java
  • 64位整数乘法

      题目大意:给定两数a,b和模数p,求a*b mod p的值。

    解法一:迭代累加法

      用类似于快速幂的思想,我们把a*b看作b个a相加,每次将各项两两合并,然后令b除以2。特判b不是2的倍数时把单独的一项累积到答案上。复杂度为对数级别。

    代码:

    1. #include <cstdio>  
    2. #include <iostream>  
    3. #include <cstring>  
    4. using namespace std;  
    5. long long p, a, b;   
    6. long long pro(long long a, long long b, const long long &p) {  
    7.     long long ans = 0;  
    8.     while (b) {  
    9.         if (b & 1)  
    10.             ans = (ans + a) % p;  
    11.         b >>= 1;  
    12.         a = (a << 1) % p;  
    13.     }  
    14.     return ans;  
    15. }  
    16. int main() {  
    17.     cin >> a >> b >> p;  
    18.     cout << pro(a, b, p);  
    19.     return 0;  
    20. }  

    解法二:转化原式后O(1)求解

      这个方法我想了好久才明白……首先,在c++中,除法是比乘法优先的。算法进阶上给出的程序并没有说明这点。

      我们考虑模运算的数学定义:

      a * b % p = a * b - [(a * b) / p] * p = a * b - [a * (b / p)] * p

      其中a * (b/p)显然可以用long double型存下来,并且能够保证除法的精度。(long double 的精度由编译器决定,一般情况下可以存18 ~ 19位)那么我们可以先计算出上式中的两项,然后作差即可得到答案。因为二者的差小于模数p,差值一定在long long范围中,可以不用考虑高位上的溢出。

    代码:

    1. #include <cstdio>  
    2. #include <iostream>  
    3. #include <cstring>  
    4. using namespace std;  
    5. long long a, b, p;  
    6. long long mul(long long a, long long b) {  
    7.     a %= p, b %= p;   
    8.     long long t2 = (long double)(a * b) / p;  
    9.     long long del = a * b - t2 * p;  
    10.     del += p, del %= p;  
    11.     return del;  
    12. }  
    13. int main() {  
    14.     cin >> a >> b >> p;  
    15.     cout << mul(a, b);  
    16.     return 0;  
    17. }  
  • 相关阅读:
    汉罗塔问题
    有进度条圆周率计算
    turtle库笔记
    OwnCloud建立属于自己私有的云存储网盘
    HTTP 常见请求状态码
    虚拟机部署Kubernetes集群
    常用文件头(16进制)
    配置LAMP环境
    Linux系统日志
    Java的socket通信与操作系统的SocketAPI关系探究
  • 原文地址:https://www.cnblogs.com/TY02/p/11240048.html
Copyright © 2011-2022 走看看