题解: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; }