zoukankan      html  css  js  c++  java
  • 【模板】快速幂

    (还记得大明湖畔的快速幂吗?)

    先提一个小问题,怎么求a的n次方?

    当然是暴力。。直接乘就好啊。。

    等等,当n=10e+9怎么办?(当然我知道这玩意一般还要再模一个c)

    难不成你还想。。(不你不想)

    这时,蒟蒻默默打出一个问号。。(所以我去学了快速幂)

    ————快速幂

    原理:

    首先,有这样一个公式

    (a*b)%c=((a%c)*(b%c))%c;

    (a^b)%c=((a%c)^b)%c

    长得好奇怪。。但其实和实数运算法则一样。。

    这样就有下面的第一步优化,为了使求出来的值不超long long 

    int ans = 1;
    a = a % c;  //加上这一句
    for(int i = 1;i<=b;i++)ans = ans * a;
    ans = ans % c;

    (但是这样也还是会超。。)

    再看一下上面的公式,既然先相乘再取余先取余再相乘再取余一样,那就可以给每一步的结果ans取余。

    int ans = 1;
    a = a % c; 
    for(int i = 1;i<=b;i++)ans = (ans * a) % c;//这里再取了一次余
    ans = ans % c;

    这时的时间复杂度为O(b)

    虽然现在不会溢出,但是当b很大的时候还是会超时

    然后,有这样一个公式

    a^b%c==((a^2)b/2)%c == ((a^2 % c)b/2)%c          b为偶数

    a^b%c==(a*(a^2)b/2)%c == (a*(a^2 % c)b/2)%c         b为奇数

    这样,就可以进一步优化为:

    int ans = 1;
    a = a % c;
    k = (a*a) % c;               //相当于用k代替了a2
    if(b%2==1)
        ans = (ans * a) % c; //如果是奇数,要多求一步,可以提前算到ans中
    for(int i = 1;i<=b/2;i++) ans = (ans * k) % c;
    ans = ans % c;

    这时的时间复杂度是O(b/2)

    还是远远不够啊。。

    但是,由上面的一次优化可以发现,我们已经把a^b%c转换成了k^(b/2)%c

    而K^(b/2)%c是可以继续迭代下去的

    例如,

    下一步再令 x=(k*k)%c 偶数就是求 x^b/4 % c 奇数就是 (x^b/4 % c*a)% c
    再下一步令 y=(x*x)%c 偶数就是求 y^b/8 % c 奇数就是 (y^b/8 % c*a)% c
        ......  直到指数b ==0
    当然,对于奇数的情形会多出一项a % c,所以为了完成迭代,当b是奇数时,我们通过ans = (ans * a) % c; 来弥多出来的这一项
    int ans = 1;
    a = a % c;
    while(b>0)
    {
          if(b % 2 == 1)ans = (ans * a) % c;   //奇数,补一项
          b = b/2;
          a = (a * a) % c;
    }
    cout<<ans<<endl;

    这时的时间复杂度是O(logb)

    就是完整的快速幂算法!

    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long int a,b,c;
    long long int ans=1,bent;
    int main()
    {
        scanf("%d%d%d",&a,&b,&c);
        bent=a;
        while(b)
        {
            if(b&1)
            ans=(ans*bent)%c;
            bent=(bent*bent)%c;
            b/=2;
        }
        printf("%d",ans);
        return 0;
    }

    看一道题吧。。这个是裸的快速幂(点击收获RP)先把板子打会吧。。

    (RP++!)

     

     

     
     

     

  • 相关阅读:
    PHP 大小写转换、首字母大写、每个单词首字母大写转换相关函数
    【论文学习4】BiSample: Bidirectional Sampling for Handling Missing Data with Local Differential Privacy
    【论文学习3】Local Differential Privacy for Deep Learning
    【论文学习2】 Differential Privacy Reinforcement Learning
    深度学习中的优化算法
    Spatial crowdsourcing
    “pip install tensorflow ”出现错误
    python或pip'不是内部或外部命令”
    pip install torch出现错误
    打不开gitHub的解决方法
  • 原文地址:https://www.cnblogs.com/Daz-Os0619/p/11469784.html
Copyright © 2011-2022 走看看