一份对于求幂方法的总结

关于乘方

1、最基本的求幂方法(同于数据极弱的题):

int temp=con;

for(int i=2;i<=a;i++) temp*=con;

可以低效求出con的a次方。

例题:输入二个正整数a,b,求a^b的值。

#include<iostream>

using namespace std;

int main()

{

int a,b;

scanf("%d%d",&a,&b);

int temp=a;

for(int i=2;i<=b;i++) temp*=a;

printf("%d",temp);

//system("pause>nul");

return 0;

}

2、利用数据库中的函数 Math.pow( )求幂;

#include<cmath>

int a=MAXN,b=MAXN;

Math.pow(a,b);

可以求出a的b次方

例题:


2^2^N,bigbigbigbigbigbign!!!!!!


难度级别:E; 运行时间限制:10000ms; 运行空间限制:65536KB; 代码长度限制:2000000B


试题描述


一个天才最近一直在思索一道题:2^2^2^22

这道题以现在的技术显然是不可能实现了

一个天才就去掉了一个2,又减去了一个2:2^2^20(也还是很可怕啊,估计有30多万位!!!!)

请你编个程序帮帮她吧。。。

23333333333333333333333333333333


输入


一个正整数N


输出


2^2^N


输入示例


输入样例1:
2
输入样例2:
3


输出示例


输出样例1:
16
输出样例2:
256


其他说明


数据范围:
2<=N<=20

这题应该使用高精度,但是既然提到了函数,就用一用函数吧。

#include<iostream>

#include<cmath>

#include<iomanip>

using
namespace std;

int
main()

{

double n,z=2;

scanf("%lf",&n);

int temp=pow(z,n);

cout<<fixed<<setprecision(0)<<pow(z,temp);

//system("pause>nul");

return 0;

}

3、用二分求幂

int
EF(int a,int b)

{

int r=1,l=a;

while(b!=0)

{

if(b%2) r*=l;

l*=l;

b>>=1;

}

return r;

}

图为二分求幂的原理:

也就是将一个较大的幂拆分为多个。

例题:


A^B


难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B


试题描述


输入两个正整数A,B,计算A的B次方的值。由于结果可能会很大(其实也就10^(10^1000000)左右),请输出它取模1000000007的值


输入


第一行为一个正整数A。
    第二行为一个正整数B。


输出


输出(A^B)mod1000000007的值。


输入示例


5
3


输出示例


125


其他说明


1<=A<=10^1000000
1<=B<=10^1000000

对于数据范围是10^10^9的题当然毫不犹豫用快速幂,但是10^10^6还是可以二分的。

#include<iostream>

#include<cstdio>

using
namespace std;

const
int mod(1000000007);

int
EF(int a,int b)

{

int r=1,l=a;

while(b!=0)

{

if(b%2) r=r*l%mod;

l*=l;

b>>=1;

}

return r%mod;

}

int
main()

{

int a,b;

scanf("%d%d",&a,&b);

printf("%d",EF(a,b)%mod);

//system("pausE>nul");

return 0;

}

4、伟大的快速幂

int
fast_mi(int a,int b)

{

int r=1,base=a;

while(b!=0)

{

if(b&1)

r*=base;

base*=base;

b>>=1;

}

return r;

}

快速幂的原理是将要求的幂转化为二进制数之后再进行运算。

举一个百度上的例子:

11的二进制是1011

11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1

因此,我们将a¹¹转化为算

所以a的11次方就是。

而且对于某些特定的题,快速幂可以有效地求出有用的数位。

int
fast_mi(int a,int b)

{

int r=1,base=a;

while(b!=0)

{

if(b&1)

r*=base;

base*=base;

b>>=1;

}

return r;

}

例题:


NOIP201305转圈游戏


难度级别: A; 编程语言:不限;运行时间限制:1000ms;
运行空间限制:51200KB; 代码长度限制:2000000B


试题描述


有n个小伙伴(编号从0到n-1)围坐一圈玩游戏。按照顺时针方向给n个位置编号,从0到n-1。最初,第0号小伙伴在第0号位置,第1号小伙伴在第1号位置,……,依此类推。
    游戏规则如下:每一轮第0号位置上的小伙伴顺时针走到第m号位置,第1号位置小伙伴走到第m+1号位置,……,依此类推,第n−m号位置上的小伙伴走到第0号位置,第n-m+1号位置上的小伙伴走到第1号位置,……,第n-1号位置上的小伙伴顺时针走到第m-1号位置。
    现在,一共进行了10^k 轮,请问x号小伙伴最后走到了第几号位置。


输入


输入共1行,包含4个整数n、m、k、x,每两个整数之间用一个空格隔开。


输出


输出共1行,包含1个整数,表示10^k轮后x号小伙伴所在的位置编号。


输入示例


10 3 4 5


输出示例


5


其他说明


数据范围:0<n<10^6,0<m<n,0<x<=n,0<k<10^9

这道题绝对是标准的快速幂应用题。因为10^10^9……

#include<iostream>

#define
ll long long

using
namespace std;

ll
n,m,x,k;

ll
fast_mi(long long x,long long y)

{

ll temp=1;

while(y)

{

if(y&1) temp=temp*x%n;

x=x*x%n;

y>>=1;

}

return temp%n;

}

int
main()

{

scanf("%lld%lld%lld%lld",&n,&m,&k,&x);

ll ans=fast_mi(10,k)%n;

ans=ans*m%n;

ans=(ans+x)%n;

printf("%lld",ans);

//system("pause>nul");

return 0;

}

总结:快速幂无疑是求幂问题中的万能钥匙,多用为妙。(注:先前的几个例子想要AC都得用快速幂。)

时间: 2024-10-06 10:30:13

一份对于求幂方法的总结的相关文章

二分求幂,快速求解a的b次幂

一个引子 如何求得a的b次幂呢,那还不简单,一个for循环就可以实现! void main(void) { int a, b; int ans = 1; cin >> a >> b; for (int i = 1; i <= b; i++) { ans *= a; } cout << ans; } 那么如何快速的求得a的b次幂呢?上面的代码还可以优化吗? 当然是ok的!下面就介绍一种方法-二分求幂. 二分求幂 所谓二分求幂,即是将b次幂用二进制表示,当二进制位k位

NYOJ--102--次方求模(快速求幂取模)

次方求模 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 求a的b次方对c取余的值 输入 第一行输入一个整数n表示测试数据的组数(n<100)每组测试只有一行,其中有三个正整数a,b,c(1=<a,b,c<=1000000000) 输出 输出a的b次方对c取余之后的结果 样例输入 3 2 3 5 3 100 10 11 12345 12345 样例输出 3 1 10481 1 /* 2 Name: NYOJ--102--次方求模 3 Copyright: ?

斐波那契加求幂运算

斐波那契博大精深啊,还有求幂的迭代也有点意思 1 //斐波那契有好多中方法 2 #include <iostream> 3 #include <deque> 4 using namespace std; 5 6 //注意普通斐波那契,在太大数时就会发生越界,比如long long 只能存表示第92个数,这些都是小的斐波那契,当要大时,就得用大数方法了 7 //用int ,只能到第46个,47就不行了,unsighed int 只能到92 8 int fibnaq(int n) //

求幂运算、多项式乘法及Horner法则的应用

一,两种不同的求幂运算 求解x^n(x 的 n 次方) ①使用递归,代码如下: 1 private static long pow(int x, int n){ 2 if(n == 0) 3 return 1; 4 if(n == 1) 5 return x; 6 if(n % 2 == 0) 7 return pow(x * x, n / 2); 8 else 9 return pow(x * x, n / 2) * x; 10 } 分析: 每次递归,使得问题的规模减半.2到6行操作的复杂度为

A sequence of numbers(快速求幂)

题目描述 Xinlv wrote some sequences on the paper a long time ago, they might be arithmetic or geometric sequences. The numbers are not very clear now, and only the first three numbers of each sequence are recognizable. Xinlv wants to know some numbers in

快速求幂

快速幂在算指数时是很高效的,他的基本原理是二进制. 如果要算 2^5,可以直接2*2*2*2*2 但是如果要算 3^999,指数N太大,计算太慢,所以有一种快速的解法. @@@@@@@@@@@@@@@@@@@@@@@@ 以3^21为例. 2^21=(2^16)×(2^4)×(2^1) 21的二进制可以写成(10101)----------------而10101可以写成1*2^4+0*2^3+1*2^2+0*2^1+1*2^0 可以明显看出, 每一个香对应着上边的指数.   2^4=16 2^2

快速求幂运算笔记

如何快速求x得n次方呢? 首先C++里面有个pow如何实现呢?自己查查,里面使用double,肯定更麻烦,还有jianzhi 我们会顺手写下 int res=1; for(int i=1;i<=n;i++) { res*=x; } 学习一下快速幂,logn内计算出来,使用N的二进制,只需要logN就可以计算. 正要的就是计算每个为1对应的基数.列入: 11是多少?是二进制的话,就是1*2^1+1 那么x^(11)呢,两个1对应的基数是多少呢?低位1对应的是X,高位1对应的是X^2,因此,就是位于

二分求幂(快速求幂,二进制求幂)

二分求幂, 非递归求法(二进制求法): 比如 2^5就是5个2相乘,按照5的二进制求 3^10就是8个3相乘,再2个3相乘. 处理幂的二进制,具体实现代码如下: long long quickmulti(long long a,long long b) { long long res=1; while(b) { if(b&1) //如果最后一位为1,则res*=a; res*=a; a*=a; //a*=a b>>=1; //b%=2 } return res; }

整数求幂

问题描述:求一个整数的n次幂,对m取余. 思路一:简单循环 1 int Pow(int num, int n, int m) 2 { 3 int res = 1; 4 5 while (n--) { 6 res *= num; 7 } 8 9 return res % m; 10 } 以上代码有个隐患,当n足够大的时候,res会溢出,因此需要优化. 有这样一个公理:两个数的积对另一个数取余,等于这两个数分别对第三个数取余的乘积再对第三个数取余.也就是a*b%c = (a%c)*(b%c)%c 根