快速幂:
#include<iostream>
using namespace std;
long long qmi(long long a,int b,int p)
{
long long res=1;
while(b)//对b进行二进制化,从低位到高位
{
//如果b的二进制表示的第0位为1,则乘上当前的a
if(b&1) res = res *a %p;
//b右移一位
b>>=1;
//更新a
a=a*a%p;
}
return res;
//a:4 b:3 p:9
//二进制b 11 1
//res 1*4%9=4 4*7%9=1
//b 1 0
//a 4*4%9=7 16*16%9=112
//因为:2^0=1,2^1=2,2^2=4,2^3=8...
//根据公式:b=3,所以2^0+2^1=b,与这个指数上面的b算的一样
//所以(4^2^0%9*4^2^1%9)%9=(4*7)%9=28%9=1,这个就是上面的res
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int a,b,p;
long long res=1;
scanf("%d%d%d",&a,&b,&p);
res = qmi(a,b,p);
printf("%d\n",res);
}
return 0;
}
快速幂求逆元:
注意:p只能是质数,否则只能用扩展欧几里得算法求解
#include<iostream>
using namespace std;
long long qmi(long long a,int b,int p)
{
long long res=1;
while(b)//对b进行二进制化,从低位到高位
{
//如果b的二进制表示的第0位为1,则乘上当前的a
if(b&1) res = res *a %p;
//b右移一位
b>>=1;
//更新a
a=a*a%p;
}
return res;
//a:8 b:5-2=3 p:5
//二进制b 11 1
//res 1*8%5=3 3*4%5=2
//b 1 0
//a 8*8%5=4 4*4%5=1
//因为:2^0=1,2^1=2,2^2=4,2^3=8...
//根据公式:b=3,所以2^0+2^1=b,与这个指数上面的b算的一样
//所以(8^2^0%5*8^2^1%5)%5=(3*4)%5=12%5=2,这个就是上面的res
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int a,p;
long long res=1;
scanf("%d%d",&a,&p);
if(a % p == 0) printf("impossible\n");
else printf("%d\n",qmi(a,p-2,p));
}
return 0;
}