• 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. }  
  • 相关阅读:
    从Oracle提供两种cube产品说开
    Sql Server DWBI的几个学习资料
    Unload Oracle data into text file
    初学Java的几个tips
    我常用的Oracle知识点汇总
    benefits by using svn
    如何在windows上使用putty来显示远端linux的桌面
    building commercial website using Microsoft tech stack
    Understand Thread and Lock
    Update google calendar by sunbird
  • 原文地址:https://www.cnblogs.com/TY02/p/11240048.html
Copyright © 2020-2023  润新知