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

    原题链接:64位整数乘法

    解题思路

    方法一

    类似快速幂的思想,把整数 b 用二进制表示,即b=c(k-1)pow(2,k-1)+c(k-2)pow(2,k-2)+......+c(0)pow(2,0),那么a*b=c(k-1)*a*pow(2,k-1)+c(k-2)*a*pow(2,k-2)+......+c(0)*a*pow(2,0)
    因为a*pow(2,i)=(a*pow(2,i-1))*2,若已求出a*pow(w,i-1) mod p,则计算(a*pow(2,i-1))*2 mod p时,运算过程中每一步的结果都不超过2*pow(10,18),仍然在64位整数 longlong 的表示范围内,所以很容易通过 k 次递推求出每个乘积项。当 c(i)=1 时,把乘积项累加到答案中即可。

    样例代码

    #include<bits/stdc++.h>
    using namespace std;
    unsigned long long mul(unsigned long long a,unsigned long long b,unsigned long long p)
    {
        a%=p,b%=p;
        unsigned long long c=(long double)a*b/p;
        unsigned long long x=a*b,y=c*p;
        long long ans=(long long)(x%p)-(long long)(y%p);
        if(ans<0)
            ans+=p;
        return ans;
    }
    int main()
    {
        long long a,b,p;
        cin>>a>>b>>p;
        cout<<mul(a,b,p);
        return 0;
    }
    

    方法二

    如果直接计算a乘b这会超过 long long 的最大范围,所以采用类似于快速幂的思想
    把 b写成二进制形式,然后如果某位上为1就加上它a*(2^n)次方(n与这位的位置有关)
    并且每次计算后取模就可以了

    例:计算 3*7
    
    7的二进制 111
    3*(2^0)=3
    3*(2^1)=6
    3*(2^2)=12
    

    观察可发现每次的可由前一次*2推出(记得取模)

    样例代码

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main()
    {
        ll a , b , p , res;
        cin >> a >> b >> p;
        res = 0;
        while (b)
        {
            if (b & 1)
                res = (res + a) % p;
            b >>= 1;
            a = 2 * a % p;
        }
        cout << res;
        return 0;
    }
    
  • 相关阅读:
    uva 12096
    uva 705
    uva 657
    uva 10129
    uva 816 BFS求最短路的经典问题……
    uva 1103
    uva 699
    这是昨天的内容,就这样慢慢整吧,然后,荒废了好多时间啊!!
    今天就这么乱糟糟的过啦~刚刚接触html,就稍微写了一下,明天加油,今天直接贴图
    uva 548 tree
  • 原文地址:https://www.cnblogs.com/hnkjdx-ssf/p/14058494.html
Copyright © 2011-2022 走看看