• 洛谷 P1226 【模板】快速幂||取余运算


    洛谷 P1226 【模板】快速幂||取余运算

    题目链接

    https://www.luogu.org/problemnew/show/P1226


    题目描述

    输入b,p,k的值,求b^p mod k的值。其中b,p,k*k为长整型数。


    输入输出格式

    输入格式:

    三个整数b,p,k.

    输出格式:

    输出“b^p mod k=s”

    s为运算结果


    输入输出样例

    输入样例#1:

    2 10 9

    输出样例#1:

    2^10 mod 9=7


    这道题有各种各样的做法,来整理一下几种思路吧

    做法1(来自一本通)

    思路

    1.本题主要的难点在于数据规模很大(b,p都是长整型数),对于(b^p)显然不能死算,那样的话时间复杂度和编程复杂度都很大。

    2.下面先介绍一个原理:A*B%K = (A%K )*(B% K )%K。显然有了这个原理,就可以把较大的幂分解成较小的,因而免去高精度计算等复杂过程。那么怎样分解最有效呢?

    3.显然对于任何一个自然数P,有P=2 * P/2 + P%2,如19=2 * 19/2 + 19%2=2*9+1,利用上述原理就可以把B的19次方除以K的余数转换为求B的9次方除以K的余数,即B19=B2*9+1=B*B9*B9,再进一步分解下去就不难求得整个问题的解。

    (额外提一点,最后输出的时候也不要忘记再取模一下,因为没取模我WA了一个点)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    long long b,p,k,a;
    
    long long f(long long p){
    	if(p==0)return 1;
    	long long tmp=f(p/2)%k;
    	tmp=(tmp*tmp)%k;
    	if(p%2==1)tmp=(tmp*b)%k;
    	return tmp;
    }
    
    int main(){
    	scanf("%lld%lld%lld",&b,&p,&k);
    	long long tmpb=b;
    	b%=k;
    	printf("%lld^%lld mod %lld=%lld
    ",tmpb,p,k,f(p)%k);
    	return 0;
    }
    

    做法二

    思路

    首先要知道,余数是有规律的,除以任何数都是这样
    拿样例来说吧,

    b=2,p=10,k=9
    2^1=2 2%9=2
    2^2=4 4%9=4
    2^3=8 8%9=8
    2^4=16 16%9=7
    2^5=32 32%9=5
    2^6=64 64%9=1
    2^7=128 128%9=2

    我们会发现,余数到2^7的时候就已经跟2^1重复了 每一个数都是一样的

    将重复的次数算出,最后在重算一次,就可以找到答案

    注意:

    1.不能用数组存余数,空间承受不起

    2.一边乘一边除,否则会死得很惨

    代码

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    long long b,p,k,s,t;
    int main()
    {
        cin>>b>>p>>k;
        cout<<b<<"^"<<p<<" mod "<<k<<"=";
        s=b%k;
        t=1;
        for (int i=2;i<=p;i++)
        {
            s=s*b%k;
            if (s==b%k) break;
            t++;
        }
        p=p%t;s=1;
        if (p==0) p=t;
        for (int i=1;i<=p;i++)
        s=s*b%k;
        cout<<s;
        return 0;
    }
    

    (来自洛谷)


    做法三

    思路

    直接使用常规的快速幂算法

    所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。

    代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    int power(int b,int p,int k);
    int b,p,k;
    
    signed main() {
    	cin>>b>>p>>k;
    	int www=p;
    	cout<<b<<"^"<<www<<" mod "<<k<<"="<<power(b,p,k)%k;
    }
    
    int power(int b,int p,int k) {
    	int ans=1;
    	b%=k;
    	while(p) {
    		if(p&1)
    			ans=(ans*b)%k;
    		p>>=1;
    		b=(b*b)%k;
    	}
    	return ans;
    }
    
  • 相关阅读:
    maven 常用命令
    navicat 破解
    linux命令
    Git常用命令
    关于近期工作的总结
    ES6新特性学习
    Hadoop初步学习
    串行、并行与并发的理解
    通过Spring profile方式实现多环境部署
    使用MySQL乐观锁解决超卖问题
  • 原文地址:https://www.cnblogs.com/loceaner/p/10759021.html
Copyright © 2020-2023  润新知