首页 > 代码库 > HDU 2815 扩展baby step giant step 算法
HDU 2815 扩展baby step giant step 算法
题目大意就是求 a^x = b(mod c) 中的x
用一般的baby step giant step 算法会超时
这里参考的是http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4
map平衡树查找值
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <map> 6 using namespace std; 7 #define ll long long 8 9 int q_pow(int a , int b , int mod)10 {11 ll ans = 1;12 while(b)13 {14 if(b&1) ans =((ll)ans*a)%mod;15 a = ((ll)a*a)%mod;16 b>>=1;17 }18 return ans;19 }20 21 int gcd(int a , int b)22 {23 if(b == 0)return a;24 else return gcd(b,a%b);25 }26 27 int ex_gcd(int a , int &x , int b , int &y)28 {29 if(b == 0){30 x=1 , y=0;31 return a;32 }33 int ans = ex_gcd(b , x , a%b , y);34 int t = x;35 x=y , y = t-a/b*y;36 return ans;37 }38 39 int inv(int a , int b , int mod)40 {41 int x , y , d;42 d = ex_gcd(a , x , mod , y);43 int e = (ll)x*b%mod;44 return e<0?e+mod:e;45 }46 47 int BabyStep(int A,int B,int C){48 map<int,int> Hash;49 ll buf=1%C,D=buf,K;50 int i,d=0,tmp;51 for(i=0;i<=100;buf=buf*A%C,++i)52 if(buf==B) return i;53 while((tmp=gcd(A,C))!=1)54 {55 if(B%tmp)return -1;56 ++d;57 C/=tmp;58 B/=tmp;59 D=D*A/tmp%C;60 }61 Hash.clear();62 int M=(int)ceil(sqrt((double)C));63 for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)64 if(!Hash.count((int)buf))Hash[(int)buf]=i;65 for(i=0,K=q_pow((ll)A,M,C);i<=M;D=D*K%C,++i)66 {67 tmp=inv(D,B,C);68 if(tmp>=0&&Hash.count(tmp))return i*M+Hash[tmp]+d;69 }70 return -1;71 }72 int main()73 {74 // freopen("a.in" ,"r" , stdin);75 int k , p , n;76 while(scanf("%d%d%d" , &k , &p , &n) == 3)77 {78 if(n>=p){79 puts("Orz,I can’t find D!");80 continue;81 }82 int ans = BabyStep(k , n , p);83 if(ans == -1) puts("Orz,I can’t find D!");84 else printf("%d\n" , ans);85 }86 return 0;87 }
hash表查找值(效率高很多)hash是线性查找:
1 #include<iostream> 2 #include<map> 3 #include<cmath> 4 #include <cstdio> 5 using namespace std; 6 typedef long long LL; 7 const int maxn = 65535; 8 struct hash{ 9 int a,b,next; 10 }Hash[maxn << 1]; 11 int flg[maxn + 66]; 12 int top,idx; 13 //hash值插入 14 void ins(int a,int b){ 15 int k = b & maxn; 16 if(flg[k] != idx){ 17 flg[k] = idx; 18 Hash[k].next = -1; 19 Hash[k].a = a; 20 Hash[k].b = b; 21 return ; 22 } 23 while(Hash[k].next != -1){ 24 if(Hash[k].b == b) return ; 25 k = Hash[k].next; 26 } 27 Hash[k].next = ++ top; 28 Hash[top].next = -1; 29 Hash[top].a = a; 30 Hash[top].b = b; 31 } 32 //hash值查找 33 int find(int b){ 34 int k = b & maxn; 35 if(flg[k] != idx) return -1; 36 while(k != -1){ 37 if(Hash[k].b == b) return Hash[k].a; 38 k = Hash[k].next; 39 } 40 return -1; 41 } 42 int gcd(int a,int b) 43 { 44 return b?gcd(b,a%b):a; 45 } 46 int ext_gcd(int a,int b,int& x,int& y) 47 { 48 int t,ret; 49 if (!b){x=1,y=0;return a;} 50 ret=ext_gcd(b,a%b,x,y); 51 t=x,x=y,y=t-a/b*y; 52 return ret; 53 } 54 int Inval(int a,int b,int n){ 55 int x,y,e; 56 ext_gcd(a,n,x,y); 57 e=(LL)x*b%n; 58 return e<0?e+n:e; 59 } 60 int pow_mod(LL a,int b,int c) 61 { 62 LL ret=1%c; 63 a%=c; 64 while(b){ 65 if(b&1)ret=ret*a%c; 66 a=a*a%c; 67 b>>=1; 68 } 69 return ret; 70 } 71 int BabyStep(int A,int B,int C){ 72 top = maxn; ++ idx; 73 LL buf=1%C,D=buf,K; 74 int i,d=0,tmp; 75 for(i=0;i<=100;buf=buf*A%C,++i) 76 if(buf==B)return i; 77 while((tmp=gcd(A,C))!=1){ 78 if(B%tmp)return -1; 79 ++d; 80 C/=tmp; 81 B/=tmp; 82 D=D*A/tmp%C; 83 } 84 int M=(int)ceil(sqrt(C+0.5)); 85 for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i) 86 ins(i,buf); 87 for(i=0,K=pow_mod((LL)A,M,C);i<=M;D=D*K%C,++i){ 88 tmp=Inval((int)D,B,C); 89 int w ; 90 if(tmp>=0&&(w = find(tmp)) != -1) return i*M+w+d; 91 } 92 return -1; 93 } 94 int main(){ 95 int A,B,C; 96 while(scanf("%d%d%d",&A,&C,&B)!=EOF){ 97 if(B>C){ 98 puts("Orz,I can’t find D!"); 99 continue;100 }101 int tmp=BabyStep(A,B,C);102 if(tmp<0)103 puts("Orz,I can’t find D!");104 else printf("%d\n",tmp);105 }106 return 0;107 }
HDU 2815 扩展baby step giant step 算法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。