//快速幂
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
int main()
{
long long a,b,c;
while(~scanf("%lld%lld",&a,&b))
{
c=1;
while(b)
{
if(b&1)
c*=a;
b>>=1;
a*=a;
}
printf("%lld\n",c);
}
}
//快乘
#include<stdio.h>
#include<string.h>
#define LL long long
const LL mod=1e10;
LL cheng(LL x,LL y)
{
LL ans=0;
x%=mod;
while(y)
{
if(y&1)
ans+=x;
if(ans>=mod)
ans-=mod;
x<<=1;
if(x>=mod)
x-=mod;
y>>=1;
}
return ans;
}
int main()
{
LL a,b;
while(~scanf("%lld%lld",&a,&b))
{
LL ans=cheng(a,b);
printf("%lld\n",ans);
}
}
对于结果数据特别大的数据,利用快乘可以解决爆long long的问题。
题目描述
什么?听说你会快速幂?这么厉害的吗,那我就出一道快速幂的题吧! 题意很简单,给你n,m的值,我想知道n的m次方是多少,但是这个答案太大了,所以你只需要输出答案最后面的十位数字即可。
输入
T组输入,接下来的T行(T<300),每一行输入n,m(0<n<=100 ,0<=m<=1000000000)
输出
输出T行,每一行输出n^m的后十位数字(不够10位用零补)。
样例输入
3 2 10 3 3 1 1000000000
样例输出
0000001024 0000000027 0000000001
#include<stdio.h>
#include<string.h>
#define LL long long
const LL mod=1e10;
LL cheng(LL x,LL y)
{
LL ans=0;
x%=mod;
while(y)
{
if(y&1)
ans+=x;
if(ans>=mod)
ans-=mod;
x<<=1;
if(x>=mod)
x-=mod;
y>>=1;
}
return ans;
}
LL pow(LL x,LL y)
{
LL ans=1;
x%=mod;
while(y)
{
if(y&1)
ans=cheng(ans,x);
x=cheng(x,x);
y>>=1;
}
return ans;
}
int main()
{
LL m,n;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&m,&n);
printf("%010lld\n",pow(m,n));
}
}
//大佬的代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define LL long long
#define mod 10000000000
using namespace std;
//举个栗子:(a)6541341165*(b)9846541356
//将b拆开拆成,9,8,4,6,5,4,1,2,5,6
//然后把a*b变成:a*6+a*10%mod*5+a*10%mod*10%mod*2+a*10%mod*10%mod*10%mod*1+.....以此类推
//这样就能解决a*b会爆LL的问题了。
LL chengfa(LL a,LL b)
{
LL sum=0;
while(b)
{
sum=(sum+a*(b%10))%mod;
a=a*10%mod;
b=b/10;
}
return sum;
}
//LL chengfa(LL a,LL b)//如果mod为1e18的话就必须这样写了,用二进制解决这个问题
//{
// LL sum=0;
// while(b)
// {
// if(b%2==1) sum=(sum+a)%mod;
// a=(a+a)%mod;
// b=b/2;
// }
// return sum;
//}//看懂后你会发现这个代码和快速幂的代码基本上一样。*和+的区别。
LL pow(LL a,LL b)
{
LL sum=1;
while(b)
{
if(b%2==1) sum=chengfa(sum,a);
a=chengfa(a,a);
//这里的a是一个小于mod的数字,a可能是一个十位数的数字
//两个十位数相乘是二十位的数字,那么就超过了LL
//所以要想办法使得a*a不超过LL,具体看chengfa()函数。
b=b/2;
}
return sum;
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%010lld\n",pow((LL)a,(LL)b));
}
return 0;
}
再来看另一道题:
As one of the most powerful brushes, zhx is required to give his juniors
n
problems.
zhx thinks the
ith
problem's difficulty is
i
. He wants to arrange these problems in a beautiful way.
zhx defines a sequence
{ai}
beautiful if there is an
i
that matches two rules below:
1:
a1..ai
are monotone decreasing or monotone increasing.
2:
ai..an
are monotone decreasing or monotone increasing.
He wants you to tell him that how many permutations of problems are there if the sequence of the problems' difficulty is beautiful.
zhx knows that the answer may be very huge, and you only need to tell him the answer module
p
For each case, there are two integers n and p separated by a space in a line. ( 1≤n,p≤1018
2 233 3 5
2 1
In the first case, both sequence {1, 2} and {2, 1} are legal. In the second case, sequence {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1} are legal, so the answer is 6 mod 5 = 1
思路:只要确定数列的最大值所在的位置后者最小值所在的位置即可,其他的数放置在最值的两边,每个数都有两种情况。最后的结果取余p。
那么这道题的解法也同样是快速幂+快乘了。
#include<stdio.h>
#include<string.h>
#define LL long long
LL p;
LL cheng(LL x,LL y)
{
LL ans=0;
x%=p;
while(y)
{
if(y&1)
ans+=x;
if(ans>=p)
ans-=p;
x<<=1;
if(x>=p)
x-=p;
y>>=1;
}
return ans;
}
LL pow(LL n)
{
LL base=2%p,ans=1;
while(n)
{
if(n&1)
ans=cheng(ans,base);
base=cheng(base,base);
n>>=1;
}
return ans;
}
int main()
{
LL n;
while(~scanf("%lld%lld",&n,&p))
{
printf("%lld\n",(pow(n)-2+p)%p);
}
}