EXBSGS

http://210.33.19.103/problem/2183

参考:https://blog.csdn.net/frods/article/details/67639410(里面代码好像不太对)(不用求逆元的方法)

https://blog.csdn.net/zzkksunboy/article/details/73162229(要逆元的方法)

参考代码:https://blog.csdn.net/clove_unique/article/details/51227328

以下代码pojA不掉,没有unordered_map,map又T掉;要手写哈希表

https://www.luogu.org/problemnew/show/P3846

https://cn.vjudge.net/problem/POJ-3243

https://cn.vjudge.net/problem/POJ-2417

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<tr1/unordered_map>
 5 using namespace std;
 6 using namespace tr1;
 7 typedef long long LL;
 8 LL poww(LL a,LL b,LL md)
 9 {
10     LL base=a,ans=1;
11     for(;b;base=base*base%md,b>>=1)   if(b&1) ans=ans*base%md;
12     return ans;
13 }
14 LL logm(LL a,LL b,LL md)
15 {
16     if(md==0)   return -1;
17     if(a%md==0) return b?-1:(a==0);
18     if(b==1)    return a?0:-1;
19     //printf("a%lld %lld %lld\n",a,b,md);
20     //以上为特判,记一下
21     LL g,num=0,d=1;
22     while((g=__gcd(a,md))!=1)
23     {
24         if(b%g) return -1;
25         num++;b/=g;md/=g;d=d*(a/g)%md;
26         if(b==d)    return num;//特殊技巧,记一下;num==0的情况前面已经判了
27         //设gg为所有已经除过的g的积,原来b为B,此时的b实际相当于B/gg
28         //d=a^num/gg,如果a^num==B,则d==b
29     }
30     //printf("b%lld %lld %lld\n",a,b,md);
31     LL sz=sqrt(md+0.5),sz1=(md-1)/sz+1,i,now,t=poww(a,sz,md);//sz块大小,sz1块数
32     unordered_map<LL,LL> ma;
33     for(i=0,now=b%md;i<sz;i++,now=now*a%md)//x=i*sz-j,因此j属于[0,sz-1]
34     {
35         ma[now]=i;//应该使得x最小,则j应越大越好,因此相同的保留最大的
36         //printf("c%lld %lld\n",i,now);
37     }
38     for(i=1,now=d;i<=sz1;i++)//因此i属于[1,sz1]
39     {
40         now=now*t%md;
41         if(ma.count(now))   return i*sz-ma[now]+num;
42         //printf("d%lld\n",i);
43     }
44     return -1;
45 }
46 LL a,md,b,ans;
47 int main()
48 {
49     while(1){
50     scanf("%lld%lld%lld",&a,&md,&b);
51     if(a==0&&md==0&&b==0)   break;
52     ans=logm(a,b,md);
53     ans==-1?puts("No Solution"):printf("%lld\n",ans);
54     }
55     return 0;
56 }

压一下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<tr1/unordered_map>
 5 using namespace std;
 6 using namespace tr1;
 7 typedef long long LL;
 8 LL poww(LL a,LL b,LL md)
 9 {
10     LL base=a,ans=1;
11     for(;b;base=base*base%md,b>>=1)   if(b&1) ans=ans*base%md;
12     return ans;
13 }
14 LL logm(LL a,LL b,LL md)
15 {
16     if(md==0)   return -1;
17     if(a%md==0) return b?-1:(a==0);
18     if(b==1)    return a?0:-1;
19     LL g,num=0,d=1;
20     while((g=__gcd(a,md))!=1)
21     {
22         if(b%g) return -1;
23         num++;b/=g;md/=g;d=d*(a/g)%md;
24         if(b==d)    return num;
25     }
26     LL sz=sqrt(md+0.5),sz1=(md-1)/sz+1,i,now,t=poww(a,sz,md);
27     unordered_map<LL,LL> ma;
28     for(i=0,now=b%md;i<sz;i++,now=now*a%md)    ma[now]=i;
29     for(i=1,now=d;i<=sz1;i++)
30     {
31         now=now*t%md;
32         if(ma.count(now))   return i*sz-ma[now]+num;
33     }
34     return -1;
35 }
36 LL a,md,b,ans;
37 int main()
38 {
39     while(1){
40     scanf("%lld%lld%lld",&a,&md,&b);
41     if(a==0&&md==0&&b==0)   break;
42     ans=logm(a,b,md);
43     ans==-1?puts("No Solution"):printf("%lld\n",ans);
44     }
45     return 0;
46 }

 

posted @ 2018-05-14 19:27  hehe_54321  阅读(167)  评论(0编辑  收藏  举报
AmazingCounters.com