题解:BSGS
问题:map空间
BSGS判无解 a%p!=0
0与最小非负整数 有区别
函数传参类型转换int->long long long long ->int;
费马小定理充分必要 性?
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
typedef long long Lint;
int T,k;
Lint mm;
map<Lint,int>ma;
Lint ksm(Lint a,Lint p){
Lint ret=1;
for(;p;p>>=1,a=a*a%mm){
if(p&1)ret=ret*a%mm;
}
return ret;
}
void gcd(Lint a,Lint b,Lint &d,Lint &x,Lint &y){
if(b==0){
d=a;x=1;y=0;
}else{
gcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int main(){
scanf("%d%d",&T,&k);
while(T--){
if(k==1){
Lint a,p;
scanf("%lld%lld%lld",&a,&p,&mm);
printf("%lld\n",ksm(a,p));
}
if(k==2){
Lint a,c,b,x0,y0,d;
scanf("%lld%lld%lld",&a,&c,&b);
gcd(a,b,d,x0,y0);
if(c%d!=0){
printf("Orz, I cannot find x!\n");
continue;
}else{
x0=c/d*x0;b=b/d;
printf("%lld\n",(x0%b+b)%b);
}
}
if(k==3){
Lint a,c,p;
scanf("%lld%lld%lld",&a,&c,&p);
Lint m=ceil(sqrt(p));
ma.clear();
int flag=0;mm=p;
Lint tmp=ksm(a,m);
if(a%p==0){
printf("Orz, I cannot find x!\n");
continue;
}
for(Lint x=c%p,i=0;i<=m;++i,x=x*a%p)ma[x]=i;
for(Lint x=tmp%p,i=1;i<=m;++i,x=x*tmp%p){
if(ma.count(x)&&(m*i-ma[x]!=0)){
printf("%d\n",m*i-ma[x]);
flag=1;
break;
}
}
if(!flag)printf("Orz, I cannot find x!\n");
}
}
return 0;
}