【数论】快速幂及取余wikioi1497,2952

本文介绍了快速幂算法及其在计算幂次方和解决实际问题中的应用。通过递归和非递归方式实现快速幂,有效降低了时间复杂度。并提供了两个实例问题的解决方案。

前不久接触了数论,发现。。。。果然数论好难啊!!!!不过还是有一些简单的,首先快速幂及取余是要掌握的,在求幂时,如果用朴素算法,时间是O(n),而快速幂则是O(logn),举个例子,如果用朴素算法计算a^41,就需要做41 次乘法运算。时间复杂度O(n)。
使用分治算法,就有:a ^ 41=(a ^ 20) ^ 2 * a,a ^ 20=(a ^ 10) ^ 2,a ^ 10=(a ^ 5) ^ 2,a5=(a ^ 2) ^ 2 * a,a2=(a)^2。只需7 次乘法运算。时间复杂度O(logn),快速幂有递归形式及非递归形式

a^b的形式,递归版

 

long long quickpow(long long a, long long b)
{
    if (b == 0) return 1;//a^0 = 1
    long long r = quickpow(a, b / 2);//分治
    r *= r;//偶次幂
    if (b % 2)//如果是奇次幂,还需多乘一次
    r = r * a;
    return r;
}    

非递归:

long long quickpow(long long a, long long b)
{
    long long d = 1, t = a;
    while (b > 0)
    {
        if (t == 1) return d;
        if (b % 2)
        d = d * t;
        b = b / 2;
        t = t * t;
      } return d;
}                

快速幂取模 a^b % n:

long long quickdiv(long long a, long long b, long long n)
{
    long long d=1, t=a;
    while (b>0)
    {
        if (t==1) return d;
        if (b%2)
        d=d*t%n;
        b=b/2;
        t=t*t%n;
    } return d;
}
    

下面是一些题

 

wikioi1497:http://codevs.cn/problem/1497/

 

1497 取余运算

 

 时间限制: 1 s    空间限制: 128000 KB    题目等级 : 钻石 Diamond
题目描述  Description

输入b,p,k的值,编程计算bp mod k的值。其中的b,p,k*k为长整型数(2^31范围内)。

输入描述  Input Description

b p k 

输出描述  Output Description

输出b^p mod k=?

=左右没有空格

样例输入  Sample Input

2  10  9

样例输出  Sample Output

2^10 mod 9=7

【代码】:

#include<cstdio>
#include<iostream>
using namespace std;
long long b, p, k;
long long qpow()
{
    long long a = p;
    long long d = 1, t = b;
    while(a > 0)
    {
        if(t == 1)return d % k;
        if(a % 2)d = d * t % k;
        a = a / 2;
        t = t * t % k;
    }
    return d;
}
int main()
{
    scanf("%lld%lld%lld", &b, &p, &k);
    printf("%lld^%lld mod %lld=%lld\n",b,p,k,qpow());
    return 0;
}
View Code

wikioi 2952:http://codevs.cn/problem/2952/

 

 

2952 细胞分裂 2

 

 时间限制: 2 s   空间限制: 16000 KB    题目等级 : 钻石 Diamond
题目描述  Description

著名生物学家F博士发现了一种单细胞生物。

它长得像蚯蚓,分裂速度极快(每分钟一次),分裂也像蚯蚓一样,断成两段,再长成。

它很好斗,只要q只聚集在一起,就会q只一群打起来,当然都会打死。

假设一开始有1只,求a分钟后有多少只单细胞蚯蚓?

输入描述  Input Description

两个正整数A  Q

输出描述  Output Description

答案

样例输入  Sample Input

4 5

样例输出  Sample Output

1

数据范围及提示  Data Size & Hint

对于50%数据,A<=20,Q<=100.

对于全部数据,A<=2*10^9,Q<=10^8.

【代码】:

#include<cstdio>
using namespace std;
long long a,q;
long long qpow()
{
    long long d = 1, t = 2;
    while(a > 0)
    {
        if(t == 1)return d % q;
        if(a % 2)d = d * t % q;
        a /= 2;
        t = t * t % q;
    }
    return d;
}
int main()
{
    scanf("%lld%lld", &a, &q);
    printf("%lld",qpow());
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/kiritoghy/p/4689159.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值