算法原理
算法实现c++:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
long long a,b,p,m,f[10000000];
map<long long,int> mp;
long long qsm(long long x) //快速幂运算
{
long long sum=1; long long aa=a;
while (x>0)
{
if (x&1) //如果x是奇数
sum=(sum*aa)%p;
x=x>>1;
aa=(aa*aa)%p;
}
return sum;
}
int main()
{
mp.clear();//清空map
printf("a^x==b mod p\n求x=log a (b)\n");
printf("依次输入 p a b \n");
while (scanf("%lld%lld%lld",&p,&a,&b)!=EOF)
{
//p=113,a=3,b=57;//测试用例
//p=383,a=2,b=228;//测试用例
mp.clear(); //清空map
if (a%p==0) //判断a,p 是否互质,因为p 是质数,所以直接判断是否整除即可
{
printf("a,p互质,无解,请重新输入 p a b \n");
continue;
}
int flag=false;
m=ceil(sqrt(p)); //p开方,向上取整
long long ans;
for (int i=0;i<=m;i++) //把a[j]:a[0],a[1],...,a[m]分别 mod p的值存到hash表map中
{
if (i==0)
{
ans=b%p; mp[ans]=i;
continue;
}
ans=(ans*a)%p;
mp[ans]=i;
}
long long t=qsm(m); ans=1;
for (int i=1;i<=m;i++) //
{
ans=(ans*t)%p;
if (mp[ans])
{
int t=i*m-mp[ans];
printf("离散对数为x=%d\n",(t%p+p)%p);
flag=true;
break;
}
}
if (!flag)
printf("无解,请重新输入 p a b \n");
}
}
运行结果: