1.目的:快速求出
的结果 O(logk)
暴力算法:
2.思路:反复平方法
把k化成二进制
例如:4的5次方mod 10
先算出:
在把5化成二进制101,
通过查询上面的数据代入:得出结果4;
题目:
给定 nn 组 ai,bi,piai,bi,pi,对于每组数据,求出 abiimodpiaibimodpi 的值。
输入格式
第一行包含整数 nn。
接下来 nn 行,每行包含三个整数 ai,bi,piai,bi,pi。
输出格式
对于每组数据,输出一个结果,表示 abiimodpiaibimodpi 的值。
每个结果占一行。
数据范围
1≤n≤1000001≤n≤100000,
1≤ai,bi,pi≤2×1091≤ai,bi,pi≤2×109
输入样例:
2
3 2 5
4 3 9
输出样例:
4
1
代码:
#include<iostream>
#include<algorithm>
using namespace std;
// |和& 都是按位
typedef long long LL;
/*
int qmi(int a,int b,int c)
{
int ans=1;
while(b){
if(b%2==1) //判断指数是奇数还是偶数
{
ans=ans*a; 将ans乘a
a=a*a; 将底数平方
b=b/2; 指数除以2
例如:3^10=(3^2)^5=9^5=9*9^4=9*(81)^2=9*(81^2)^1;
}
else //如果是偶数的话直接将底数平方指数除以2
{
a=a*a;
b=b/2;
}
}
}
以上还没有取模,因此以上对ans=ans*a%c;a=a*a%c才算结束,从哪里取模都是一个效果
以下是对以上过程的简单写法
*/
LL qmi(LL a,LL k,LL p){
LL res=1;
while(k) //对k二进制化,从低位到高位
{
//如果
if(k&1) res=(LL) (res*a)%p;
k>>=1;
a=(LL) (a*a)%p;
}
return res;
}
int main () {
int n;
scanf("%d",&n);
while(n--)
{
int a,k,p;
scanf("%d%d%d",&a,&k,&p);
cout << qmi(a,k,p)<< endl;
}
return 0;
}
代码2:
#include<iostream>
using namespace std;
typedef long long ll;
ll ksm (ll a,ll b,ll c)
{
if(b==0) return 1%c; //出口
ll ans;
if(b%2==0) //偶数
{
ll now =ksm(a,b/2,c);
ans=(now*now)%c;
}
else
{
ll now = ksm (a,b/2,c);
ans=(now*now%c)*a%c;
}
return ans;
}
int main() {
ll a,b,c;
cin>>a>>b>>c;
cout<<ksm(a,b,c);
return 0;
}
快速乘和快速幂
#include<iostream>
using namespace std;
typedef long long ll;
//快速幂的扩展 :a,b,c<=10^18
//数论知识:(a+b)%c==((a%c)+(b%c))%c
// (a*b)%c==((a%c)*(b%c))%c
ll chengfa (ll a,ll b,ll c)//快速乘实现a*b
{
ll ans;
if(b==0) return 0; //a*0
if(b%2==0)
{
ll now =chengfa(a,b/2,c);
ans=(now+now)%c;
}
else
{
ll now=chengfa(a,b/2,c);
ans=(((now+now)%c)+a%c)%c;
}
return ans;
}
ll ksm_up(ll a,ll b,ll c)
{
ll ans;
if(b==0) return 1%c;
if (b%2==0)
{
ll now =ksm_up(a,b/2,c);
ans=chengfa(now,now,c);
}
else
{
ll now =ksm_up(a,b/2,c);
ans=chengfa(chengfa(now,now,c),a,c);
}
return ans;
}
//快速幂
ll ksm (ll a,ll b,ll c)
{
if(b==0) return 1%c; //出口
ll ans;
if(b%2==0) //偶数
{
ll now =ksm(a,b/2,c);
ans=(now*now)%c;
}
else
{
ll now = ksm (a,b/2,c);
ans=(now*now%c)*a%c;
}
return ans;
}
int main() {
ll a,b,c;
int n;
cin>>n;
while(n--)
{
cin>>a>>b>>c;
cout<<ksm_up(a,b,c)<<endl;
}
return 0;
}