zoukankan      html  css  js  c++  java
  • 快速幂和快速乘

    题目    a^b  多组输入a,b   求a^b的个位数

    快速幂:

    #include<stdio.h>
    int ksm(long long a,long long b,long long c) 
    {
        int ans=1;
        while(b)
        {
            if(b&1)
            {
                ans=(ans*a)%c;
            }
            a=(a*a)%c;
            b=b/2;
        }
        return ans;
    }     
    int main()
    {
        long long n,m;
        while(~scanf("%lld %lld",&n,&m))
            printf("%lld
    ",ksm(n,m,10));
        return 0;
    } 

    当a,b很大的时候 在10^9时,用常规的方法就容易超时

    所以就优化

    首先n^x * x^y = n^(x+y),这个是显然的吧……
    那么由此可以推出
    n^m = n^x1 * n^x2 * ... * n^xi ,其中 x1 + x2 + ... + xi = m
    那么,我们应该找到一种最优的方式把m分解,然后用可以很容易计算出来的n^x值相乘,就可以得到n^m的答案。
    什么样的n^x算起来最快呢?
    x = 1 , n^x = n
    x = 2 , n^x = n^2
    x = 4 , n^x = n^4 = (n^2)^2
    x = 8 , n^x = n^8 = (n^4)^2
    ....
    然后,我们知道任何一个数都可以轻松用1,2,4,8,16...的和表示出来,即,把这个数转为二进制即可。
    那么对于任意一个n^m,我们就可以在O(log m)的时间内完成了。
    For example: 求2^13
    2^13 = 2^1 * 2^4 * 2^8
    就可以了……
     
     
    快速乘
    #include<stdio.h>
    long long ksm(long long,long long,long long);
    long long ksc(long long,long long,long long);
    int main()
    {
        long long n,m;
        while(~scanf("%lld%lld",&n,&m))
            printf("%lld
    ",ksm(n,m,10));
        return 0;
    }
    long long ksm(long long a,long long b,long long c)
    {
        long long ans=1;
        while(b)
        {
            if(b%2)
                ans=ksc(ans,a,10)%c;
            a=(a*a)%c;
            b/=2;    
        }
        return ans;
    }
    long long ksc(long long a,long long b,long long c)
    {
        long long ans=0;
        while(b)
        {
            if(b%2)
                ans=(ans+a)%c;
            a=(a+a)%c;
            b/=2;    
        }
        return ans;
    }

    当a,b<=10^18时   快速幂也不能解决了  所以引入快速乘

    沿用之前的方法,但是注意这里的模数是10^18
    之前10^9*10^9 long long 可以存下

    考虑到幂次可以转换成连续乘
    连续乘可以转换成连续加
    a^4 = a*a*a*a
    a*a =(a+a+a.....a)
    注意到两个10^18的数相加是可以的
    同样我们得到一个快速乘

    比如计算出a,2a,4a,8a,16a
    每次乘二,不会爆

     
  • 相关阅读:
    java中的静态代理、jdk动态代理和cglib动态代理
    第三方支付熟悉
    C#进制转换
    维翔主机asp主机使用遇到的问题及解决方案总结
    windows上JSP开发环境全搭建
    文件校验工具的开发及问题
    C#加密算法总结
    WampServer搭建php环境可能遇到的问题
    分分钟搭建自己的微信聊天机器人
    KindEditor编辑器在ASP.NET中的使用
  • 原文地址:https://www.cnblogs.com/tianming1/p/10071706.html
Copyright © 2011-2022 走看看