1. 程式人生 > >exbsgs

exbsgs

break str ini mem sca mod als () %d

#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=31630;//sqrt fai()
const int mod=100003;
ll C,A,B;
ll ni[N];
struct node{
    int nxt[mod],val[mod],id[mod],cnt;
    
int hd[mod]; void init(){ memset(nxt,0,sizeof nxt),memset(val,0,sizeof val),memset(id,0,sizeof id); memset(hd,0,sizeof hd),cnt=0; } void insert(ll x,int d){ int st=x%mod; for(int i=hd[st];i;i=nxt[i]){ if(val[i]==x) return; } val[++cnt]=x,nxt[cnt]=hd[st],id[cnt]=d,hd[st]=cnt; }
int find(ll x){ int st=x%mod; for(int i=hd[st];i;i=nxt[i]){ if(val[i]==x) return id[i]; } return -233; } }ha; ll qm(ll a,ll b,ll p){ ll ret=1,base=a; while(b){ if(b&1) ret=(base*ret)%p; base=(base*base)%p; b>>=1
; } return ret; } int gcd(int a,int b){ return (b==0)?a:gcd(b,a%b); } int BSGS(ll a,ll b,ll c){ int up=(int)floor(sqrt(1.0*c-1)); ni[0]=1; for(int i=1;i<=up;i++){ ni[i]=qm(qm(a,i*up,c),c-2,c); } for(int i=0;i<=up-1;i++){ ll kk=qm(a,i,c); ha.insert(kk,i); } for(int i=0;i<=up;i++){ ll bb=b*ni[i]%c; int kk=ha.find(bb); if(kk>=0) return i*up+kk; } return -233; } int EXBSGS(){ int num=0; int yC=C; ll ji=1; int ret=0x3f3f3f3f; bool flag=false; while(1){ int g=gcd(A,C); if(g==1) break; if(B%g) { flag=true;break; } B/=g,C/=g,ji=(ji*A/g)%C; num++; } if(!flag){ ll ni=1; if(C!=1) ni=qm(ji,C-2,C); ll NB=B*ni; ret=BSGS(A,NB,C); } for(int i=0;i<=num;i++){ ll kk=qm(A,i,yC); if(kk%yC==B) return i; } if(ret>=0) return ret+num; else return -233; } int main(){ while(1){ scanf("%lld%lld%lld",&A,&C,&B); if(A==0&&B==0&&C==0) break; ha.init(); B%=C; int ret=EXBSGS(); if(ret>=0){ printf("%d\n",ret); } else{ puts("No Solution"); } } return 0; }

poj3243

exbsgs