快速幂 快速乘

  • 快速幂
    一个整数可以被拆分成若干个2的幂的和. 对于幂运算中的\(a^b\),我们也可以将b进行二进制拆分.
    当求解\(a^b\)的时候,如果b是奇数,则拆成\(a\ast a^{b-1}\)
    当b为偶数,则拆成\(a^{b/2}\ast a^{b/2}\)
    使用倍增法可以将其从\(O(b)\)优化到\(O(logb)\)

    int poww(int a,int b){
        int ans = 1,base = a;
        while(b>0){
              if(b&1)
                    ans *= base;
              base *= base;
              base>>=1;
        }
        return ans;
    }    
    

    快速幂取模
    根据同余定理,我们可以得知 \((a\ast b)\%m = ((a\%m)\ast (b\%m))\%m\)
    通过这个可以推出
    \((a^b)\%m = (a\%m)^b\%m\)

    int poww(int a,int b){
        int ans = 1,base = a;
        while(b>0){
              if(b&1)
                    ans = (1LL*ans*base)%m;
              base = (1LL*base*base)%m;
              b>>=1;
        }
        return ans;
    }   
    
  • 快速乘
    \(O(log)\) 快速乘
    仿照快速幂的方式。把乘法换成加法。

    ll ksc(ll a, ll b, ll m){
        ll res = 0;
        while(b){
              if(b&1) res = (res + a)%m;
              a = (a<<1)%p; b >>= 1;
        }
        return res;
    }
    

    \(O(1)\)快速乘

    ll ksc(ll a,ll b,ll m){
        ll z = (ld)a/m*b;
        ll res = (ull)a*b - (ull)z*m;
        return (res+m)%m;
    }
    

    利用ull 溢出后从0开始,且两个溢出的数差值不变来计算取模后的值(余数)。

posted @ 2020-06-23 22:05  Cha2a_zzZ  阅读(129)  评论(0)    收藏  举报