hdu 2815 baby_step c可为非素数

解方程 a^x=b(mod c) c为可以为合数,参考AC大牛的http://hi.baidu.com/aekdycoin/blog/item/b317ca18bb24334942a9ad55.html

 

  1 #include <iostream>
2 #include <stdio.h>
3 #include <cmath>
4 using namespace std;
5 typedef long long ll;
6 const int maxn=65535;
7 struct Hashh
8 {
9 int a,b,next;
10 }Hash[maxn<<1];
11
12 int flag[maxn+100];//注意要赋初值0
13 int top,idx;//注意要赋初值maxn
14
15 void ins(int a,int b)
16 {
17 int k=b&maxn;//maxn=11…111,若比maxn大,取前16位,否则与原freopen("in.txt","r",stdin);相等
18 if(flag[k]!=idx)//第b&maxn个槽为空
19 {
20 flag[k]=idx;
21 Hash[k].a=a;
22 Hash[k].b=b;
23 Hash[k].next=-1;
24 return ;
25 }
26 //第b&maxn个槽不为空
27 while(Hash[k].next!=-1)//到链表的最后一个
28 {
29 if(Hash[k].b==b) return;//若b已经存在,返回
30 k=Hash[k].next;
31 }
32 Hash[k].next=++top;
33 Hash[top].next=-1;
34 Hash[top].a=a;
35 Hash[top].b=b;
36 }
37
38 int find(int b)
39 {
40 int k=b&maxn;
41 if(flag[k]!=idx) return -1;//为空
42 while(k!=-1)
43 {
44 if(Hash[k].b==b) return Hash[k].a;
45 k=Hash[k].next;
46 }
47 return -1;
48 }
49
50 int gcd(int a,int b){if(b==0)return a;return gcd(b,a%b);}
51 int exgcd(int a,int b,int &x,int &y)
52 {
53 if(0==b) {x=1;y=0;return a;}
54 int d=exgcd(b,a%b,x,y);
55 int t=x;x=y;y=t-a/b*y;
56 return d;
57 }
58
59 int exmod(ll a,int b,int c)
60 {ll ret=1%c;a%=c;while(b){if(b&1)ret=ret*a%c;a=a*a%c;b>>=1;}return ret;}
61
62 int invmod(int a,int b,int n)
63 {
64 int x,y,e;
65 exgcd(a,n,x,y);
66 e=(ll)x*b%n;
67 return e<0?e+n:e;
68 }
69
70 int babystep(int a,int b,int c)
71 {
72 top=maxn;idx++;
73 ll buf=1%c,K;
74 ll D=buf;
75 int tmp,w,i,d=0;
76 for(i=0;i<=100;i++)
77 {
78
79 if(buf==b) return i;
80 buf=buf*a%c;
81 }
82 while((tmp=gcd(a,c))!=1)
83 {
84 if(b%tmp) return -1;
85 ++d;
86 c/=tmp;
87 b/=tmp;
88 D=D*a/tmp%c;
89 }
90 int m=(int)ceil(sqrt((double)(c-1)));
91 buf=1%c;
92 for(i=0;i<=m;i++) {ins(i,buf);buf=buf*a%c;}
93 K=exmod((ll)a,m,c);
94 for(i=0;i<=m;i++)
95 {
96 tmp=invmod((int)D,b,c);
97 w=find(tmp);
98 if(tmp>=0 && (w!=-1))return i*m+w+d;
99 D=(D*K%c+c)%c;
100 }
101 return -1;
102 }
103
104
105 int main()
106 {
107 int a,b,c,tmp;
108 freopen("in.txt","r",stdin);
109 while(scanf("%d%d%d",&a,&c,&b)!=EOF)
110 {
111 if(b>=c){printf("Orz,I can’t find D!\n");continue;}
112 tmp=babystep(a,b,c);
113 if(tmp<0) printf("Orz,I can’t find D!\n");
114 else printf("%d\n",tmp);
115 }
116 return 0;
117 }



posted on 2012-03-20 11:27  Inpeace7  阅读(227)  评论(0编辑  收藏  举报

导航