快速幂和快速幂取模的算法

这是没什么用的目录

动机

为什么突然想写这个,是因为看到了POJ上的2109这道题,第一反应就是用快速幂来解题,但是自己还是不会(怪你赛后不总结查缺补漏),于是赶紧去百度查了查快速幂和对大数的取模算法,先把代码贴上来

代码

快速幂

基本原理请参见递归形式的代码

快速幂的非递归形式

long long int mi(long long int a,int b){
    long long int sum = 1; //存一下当b为奇数时多出来的那一个a
    while(b){
        if(b&1)sum*=a;	//当b为奇数时把多出来的一个a乘进去
        b>>=1;	//对b/2,奇数自动向下取整
        a*=a;	//因为a^4==(a^2)^2,所以更新a
    }
    return sum;
}

快速幂的递归形式

long long int mi(int a,int b){
    if(b==0)return 1;
    if(b&1)return a*mi(a,b-1);
    else return mi(a,b/2)*mi(a,b/2);
}

快速幂取模

这里涉及的原理除了快速幂之外,还涉及到我现在数学没学到的一个定理:多个数的积取余的余数等于每个数取余的余数的积再一次取余得到的余数
换成代码表示就是(a*b*c)%m==((a%m)*(b%m)*(c%m))%m
怎么证明请自行百度@滑稽

快速幂取模的递归形式

long long int mi(int a,int b,int m) {
    if(m==1)return 0;
    if (b == 0)return 1;
    if (b & 1) return a%m*mi(a,b-1,m)%m;
    else return mi(a,b/2,m)*mi(a,b/2,m)%m;
}

快速幂取模的非递归形式

long long int mi(long long int a,int b,int m) {
    long long int sum = 1;
    while(b){
        if(b&1)sum*=(a%m);
        b>>=1;
        a = (a*a)%m;
    }
    return sum%m;
}

后话

因为看discuss那边的说法好像是数据有问题,所以2109就没继续看下去,但是学到了东西还是蛮好的

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值