【hdu2815-Mod Tree】高次同余方程-拓展BadyStepGaintStep

http://acm.hdu.edu.cn/showproblem.php?pid=2815

题意:裸题。。。

关于拓展BSGS的详细解释我写了一篇博文:http://www.cnblogs.com/KonjakJuruo/p/5178600.html

题解:又有一个坑,就是N>=P的时候输出无解。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<algorithm>
 7 using namespace std;
 8 
 9 typedef long long LL;
10 const int SIZE=40000;
11 LL K,P,N;
12 int bl;
13 struct node{
14     LL d,id;
15 }bit[SIZE];
16 
17 bool cmp(node x,node y){
18     if(x.d==y.d) return x.id<y.id;
19     return x.d<y.d;
20 }
21 
22 LL exgcd(LL a,LL b,LL &x,LL &y)
23 {
24     if(b==0) {x=1,y=0;return a;}
25     LL tx,ty;
26     LL d=exgcd(b,a%b,tx,ty);
27     x=ty;y=tx-(a/b)*ty;
28     return d;
29 }
30 
31 LL find(LL x)
32 {
33     int l=0,r=bl;
34     while(l<=r)
35     {
36         int mid=(l+r)>>1;
37         if(bit[mid].d==x) return bit[mid].id;
38         if(bit[mid].d<x) l=mid+1;
39         if(bit[mid].d>x) r=mid-1;
40     }
41     return -1;
42 }
43 
44 LL exBSGS()
45 {
46     if(N>=P) return -1;
47     LL t,m,a,b,c,g,k,x,y,add,pm,am;
48     k=1;a=K;b=N;c=P;add=0;t=1;
49     for(int i=0;i<=100;i++)//在约分前
50     {
51         if(t%c==b) return i;
52         t=t*a%c;
53     }
54     while((g=exgcd(K,c,x,y)) != 1)
55     {
56         k=(k*K/g)%c;
57         c/=g;//不是mod
58         if(b%g) return -1;
59         b/=g;add++;
60     }
61     m=(LL)(ceil((double)sqrt((double)c)));
62     pm=1%c;bit[0].d=k%c;bit[0].id=0;
63     for(int i=1;i<=m;i++)
64     {
65         bit[i].d=bit[i-1].d*a%c;
66         bit[i].id=i;
67         pm=pm*a%c;
68     }
69     sort(bit,bit+1+m,cmp);
70     bl=0;
71     for(int i=1;i<=m;i++)
72     {
73         if(bit[i].d!=bit[bl].d) bit[++bl]=bit[i];
74     }
75     exgcd(pm,c,x,y);
76     am=x%c+c;//x
77     t=b%c;
78     for(int i=0;i<=m;i++)
79     {
80         x=find(t);
81         if(x!=-1) return i*m+x+add;
82         t=t*am%c;
83     }
84     return -1;
85 }
86 
87 int main()
88 {
89     // freopen("a.in","r",stdin);
90     // freopen("a.out","w",stdout);
91     while(scanf("%I64d%I64d%I64d",&K,&P,&N)!=EOF)
92     {
93         LL ans=exBSGS();
94         if(ans==-1) printf("Orz,I can’t find D!\n");
95         else printf("%I64d\n",ans);
96     }
97     return 0;
98 }
hdu2815

 

posted @ 2016-02-04 08:34  拦路雨偏似雪花  阅读(296)  评论(0编辑  收藏  举报