zoukankan      html  css  js  c++  java
  • 快速乘法(基于快速幂)

    快速乘法的思想和快速幂的思想一样,快速幂是求一个数的高次幂,快速乘法是求两个数相乘,什么时候才用得到快速乘法呢,当两个数相称可能超过long long 范围的时候用,因为在加法运算的时候不会超,而且可以直接取模,这样就会保证数据超不了了。具体拿一个BestCoder的题目来示例。题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5187

    这个题先找规律,然后在求快速乘法和快速幂结合起来。题目推出来通式是:2n-2

    推的过程就是一共有四种情况: 升升,升降,降升,降降,其中升升和降降最简单,一共有两种,复杂的就是升降和降升这两种情况,首先来看降生,那么ai一定是最小值,因为两边都算ai了,所有当在第一个空的时候,前面一共有Cn-11, 后面就自动的确定了,在第二位的时候,有Cn-12, 同理到最后Cn-1n-2,所以加起来就是2n-1-2,这是降升,同理升降也是这么多,所以最后结果就是(2n-1-2) * 2 + 2 = 2n-2;下面就是快速幂了,由于题目给的n特别大,所以直接快速幂会超long long,看代码:

    #include<iostream>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    typedef long long LL;
    
    LL fast_multi(LL m, LL n, LL mod)//快速乘法 
    {
        LL ans = 0;//注意初始化是0,不是1 
        while (n)
        {
            if (n & 1)
                ans += m;
            m = (m + m) % mod;//和快速幂一样,只不过这里是加 
            m %= mod;//取模,不要超出范围 
            ans %= mod;
            n >>= 1;
        }
        return ans;
    }
    LL fast_pow(LL a, LL n, LL mod)//快速幂 
    {
        LL ans = 1;
        while (n)
        {
            if (n & 1)
                ans = fast_multi(ans, a, mod);//不能直接乘 
            a = fast_multi(a, a, mod);
            ans %= mod;
            a %= mod;
            n >>= 1;
        }
        return ans;
    }
    
    int main()
    {
        LL n, p;
        while (~scanf("%I64d %I64d", &n, &p))
        {
            if (n == 1)//特判一下 
            {
                printf("%I64d
    ", 1 % p);
                continue;
            }
            printf("%I64d
    ", (fast_pow(2, n, p) - 2 + p) % p);//这一步注意,不要为负数 
        }
        return 0;
    }
  • 相关阅读:
    CEPH篇 目录
    kubernetes篇 容器用户权限控制
    深度学习篇-如何理解置信区间
    Mac软件安装篇 for Mac
    JAVA进阶篇 内存模型
    负载均衡篇 不同层次的负载均衡(2/3/4/7)
    NETTY篇 一篇文章看懂NETTY
    base64加密后无法解密
    Spring-Cloud-Gateway 从升级到放弃
    spring gateway 截取response 长度缺失
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4342847.html
Copyright © 2011-2022 走看看