关于乘方
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都得用快速幂。)