标签:class 正是 int ant std ++ clu oid error
首先要保证底数是原根,才有求解之说呐。
介绍一种BSGS(BabyStepGiantStep)算法,正如其名,走路分大步小步,相结合正是最好的方法。
小于$\sqrt{p}$的数打表保存,然后每次迈大步就好啦~
#include<iostream> #include<cstdio> #include<cmath> using namespace std; typedef long long i64; const int S=1e6+7; const int P=1e9+7; const int M=P-1; int bk; int f,c; int a; int h[S],p[S]; int pwr(int x,int a){ int s=1; while(a){ if(a&1) s=(i64)s*x%P; x=(i64)x*x%P; a>>=1; } return s; } void psh(int t,int x){ int k=x%S; while(h[k]){ ++k; if(k==S) k=0; } h[k]=x; p[k]=t; } int fnd(int x){ int k=x%S; while(h[k]&&h[k]!=x){ ++k; if(k==S) k=0; } return h[k]?p[k]:-1; } void init(){ bk=sqrt(P); int t=1; for(int i=0;i<bk;i++,t=(i64)t*c%P) psh(i,t); } int gtlog(int x){ int t=1,p,s=pwr(c,bk); for(int i=0;i<P;i+=bk,t=(i64)t*s%P){ p=fnd((i64)x*pwr(t,P-2)%P); if(p!=-1) return i+p; } } int main() { scanf("%d%d",&f,&c); if(pwr(c,P>>1)==1){ printf("Error"); return 0; } init(); a=gtlog(f); printf("%d\n",a); //cout<<pwr(c,a); return 0; }
标签:class 正是 int ant std ++ clu oid error
原文地址:https://www.cnblogs.com/l-ly-03/p/NumberTheory-DiscreteLogarithm.html