AC_a^b

代码:

定一个res存储结果
C++每秒执行107—— 108,如果直接用循环会超时,
aaaa… 若个数是奇数等同于 a * (a a a…)
aaaa… 若个数是偶数等同于 a*a * (a *a *a…)

相乘的个数为奇数的时候 直接将存储的结果res * a
相乘的个数为偶数的时候 将a = a * a

 

按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(b)也即是O(n)级别,快速幂能做到O(logn)。

abab,那么其实b是可以拆成二进制的,该二进制数第i位的权为2(i−1)2(i−1),例如当b==11时,a11=a(20+21+23)a11=a(20+21+23) 。

11的二进制是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1,因此,我们将a¹¹转化为算 $a^(2^0)a^(2^1)a^(2^3) $ 。

由于是二进制,很自然地想到用位运算这个强大的工具: &  和 >> ,&运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&1==0为偶,x&1==1为奇。>>运算比较单纯,二进制去掉最后一位 。

#include<iostream>
using namespace std;
int main()
{
    int a, b, p;
    cin >> a >> b >> p;
    int res = 1 % p;
    /*思路实际上是每次去用个位去模,然后乘上高位再继续模*/
    while (b)
    {
        if (b & 1)//个位是1  a&1 代表的意思是a和1做二进制的且运算 即看a的最后边那一位是不是1 是1的话 返回1 否则返回0
        {
            cout <<"(b & 1)"<< (b & 1) << endl;
            res = res * 1ll * a % p;//强制转换为long long 形式
            cout << "res"<<res << endl;
        }
        a = a * 1ll * a%p; //十位
        cout <<"a= "<< a << endl;
        b >>= 1;//个位去掉
    }
    cout << res << endl;
    return 0;
}

 

posted @ 2019-07-07 11:53  A-inspire  Views(142)  Comments(0Edit  收藏  举报