1. 程式人生 > >EXBSGS模板

EXBSGS模板

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define mod 600000
 6 using namespace std;
 7 int cnt,tot;
 8 int head[600005];
 9 long long a,b,c,x,y;
10 struct Edge{
11     int fr;
12     int val;
13     int nxt;
14     long long to;
15 }edge[600005]; 16 void init(){ 17 cnt=0; 18 memset(head,-1,sizeof(head)); 19 } 20 void addedge(int u,long long v,int w){ 21 edge[cnt].fr=u; 22 edge[cnt].to=v; 23 edge[cnt].val=w; 24 edge[cnt].nxt=head[u]; 25 head[u]=cnt++; 26 } 27 long long exgcd(long long i,long
long j,long long &x,long long &y){ 28 if(!j){ 29 x=1,y=0; 30 return i; 31 } 32 long long tmp=exgcd(j,i%j,y,x); 33 y-=(i/j)*x; 34 return tmp; 35 } 36 long long BSGS(long long A,long long B,long long C){ 37 init(); 38 int m=sqrt(C); 39 long
long mul1=1; 40 long long mul2=1; 41 for(int i=1;i<=m;i++){ 42 mul1=(mul1*A)%C; 43 long long ad=(mul1*B)%C; 44 if(!ad)return -1; 45 addedge(ad%mod,ad,i); 46 } 47 for(int i=1;i<=m+3;i++){ 48 mul2=(mul2*mul1)%C; 49 for(int j=head[mul2%mod];j!=-1;j=edge[j].nxt){ 50 long long v=edge[j].to; 51 if(v==mul2)return 1ll*i*m-1ll*edge[j].val; 52 } 53 } 54 return -1; 55 } 56 void EXBSGS(long long A,long long B,long long C){ 57 tot=0; 58 long long d=exgcd(A,C,x,y); 59 long long mul=1; 60 while(d!=1){ 61 if(B%d){ 62 if(B==1){ 63 printf("0\n"); 64 return; 65 }else{ 66 printf("No Solution\n"); 67 return; 68 } 69 } 70 B/=d,C/=d,tot++,mul*=(A/d); 71 d=exgcd(A,C,x,y); 72 } 73 d=exgcd(mul,C,x,y); 74 x=(x%C+C)%C; 75 long long ans=BSGS(A,(B*x)%C,C); 76 if(ans!=-1)printf("%lld\n",ans+tot); 77 else printf("No Solution\n"); 78 } 79 int main(){ 80 while(1){ 81 scanf("%lld%lld%lld",&a,&b,&c); 82 if(!a&&!b&&!c)break; 83 EXBSGS(a,c,b); 84 } 85 return 0; 86 }