快速加&快速幂

快速幂(乘法~乘方)

(工具 二进制优化的思想)
我们平时实现计算a^n次方通常会想到直接用1乘a循环n次
根据数学知识: 同底数幂相乘 底数不变指数相加 以及数的二进制表示
我们可以进行以下优化

将指数n转换成二进制展开式
n = x n ⋅ 2 n − 1 + . . . + x 3 ⋅ 2 2 + x 2 ⋅ 2 1 + x 1 ⋅ 2 0 \begin{align*} n &= x_{n} \cdot 2^{n-1} + ... + x_3 \cdot 2^2 + x_2 \cdot 2^1 + x_1 \cdot 2^0 \end{align*} n=xn2n1+...+x322+x221+x120

所以快速幂的思想就是:预处理出 底数为a 指数为2的k次方(k从0一直往下取取到指数二进制最后一位减1)
然后取出指数n的每一位 如果该m位是1 那么就把a的2^m次方累乘起来(m从0开始)
位数 = log ⁡ 2 ( n ) 位数 = \log_2(n) 位数=log2(n)

上取整

acwing.快速幂模板
在这里插入图片描述

//a^k%p
----------------------------
快速幂就是求在O(logK)求出a^k%p
算法原理就是预处理出a的(2的0~logK次方)就是把a^k拆乘a^(x1*2^0+x2*2^1+...)
用二进制来表示k
原本朴素是O(n) a乘k次
现在 k的二进制拆解  两数相乘 指数相加 这样就可以凑出K次方
然后发现预处理的每一项
a^(2^0) a^(2^1) a(2^2) 
a(2^n)=a(2^(n-1))^2
就是每一项等于前一项的平方 所以预处理只需要不断的平方就可以了 别忘了每一步(mod p)

----------------------------

#include <iostream>
using namespace std;
typedef long long LL;


int qmi(int a,int k,int p)
{
    int res=1;
    while(k)
    {
        if(k&1)res=(LL)res*a%p;
        k>>=1;
        a=(LL)a*a%p;
    }
    return res;
}
int main(void)
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int a,k,p;
        scanf("%d%d%d",&a,&k,&p);//n比较大 用scanf和printf快些
        printf("%d\n",qmi(a,k,p));
        
    }
    
    return 0;
    
}

快速加(龟速乘 加法~乘法)

思想和快速幂类似 将大数优化乘二进制 a*b
预处理出 1a 2a 4a 8a…然后相加
细节如代码
在这里插入图片描述acwing.64位整数乘法

#include <cstdio>
typedef long long LL;
/*
---------------
快速加:
a,b 10的18次方 如果直接乘起来会爆long long
回忆快速幂: 我们用乘法来解决乘方的问题

a*b 相当于 b个a相加

到底是多少个呢?
我们预处理出 a%p 2a %p=(a%p+a%p)%p

b*a=(k0*2^0+k1*2^1+...)*a

预处理加上判断b的第k位上是不是1
然后加起来

---------------
*/
LL qadd(LL a,LL b,LL p)
{
    LL res=0;
    while(b)
    {
        if(b&1)res=(res+a)%p;
        b>>=1;
        a=(a+a)%p;
        
    }
    return res;
}
int main(void)
{
    LL a,b,p;
    scanf("%lld%lld%lld",&a,&b,&p);
    LL res=qadd(a,b,p);
    printf("%lld\n",res);
    
    return 0;
    
}
``
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值