已知公式 X^Y mod z=k,以及x,z,k的值,你能求出y的值吗?
算法流程:
s1:i从0到100循环验证,如果满足Ai≡B(mod C),那么i就为所求,否则继续s2;
s2:令d=0,D=1,执行以下循环:
while((tmp=gcd(A,C))!=1)
{
if(B%tmp)return -1;//无解
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
s3:令m=ceil(sqrt(C));
s4:i从0到m循环执行将(i,AI%C)插入Hash表中;
s5:求的K=quick_mod(A,m,C),令i=0,如果i>m执行s6;否则求DX=B(mod C)在 [0,C-1]的解,并在Hash中查询,若查到(假设是x),则返回 i*m+x,否则D=DK%C,i=i+1,继续循环:
s6:返回-1;
这道题目除去 主函数部分,都是模版,模版好长啊,真的好长啊
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#define ll long long
#define LL __int64
#define eps 1e-8
//const ll INF=9999999999999;
#define inf 0xfffffff
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;
//
//vector<int>G[30012];
#define maxn 65535
struct hash
{
int a,b,nex;
}Hash[maxn*2];
int flg[maxn+66];
int top,idx;
void ins(int a,int b)
{
int k=b&maxn;
if(flg[k]!=idx)
{
flg[k]=idx;
Hash[k].nex=-1;
Hash[k].a=a;
Hash[k].b=b;
}
while(Hash[k].nex!=-1)
{
if(Hash[k].b==b)return;
k=Hash[k].nex;
}
Hash[k].nex=++top;
Hash[top].nex=-1;
Hash[top].a=a;
Hash[top].b=b;
}
int find(int b)
{
int k=b&maxn;
if(flg[k]!=idx)return -1;
while(k!=-1)
{
if(Hash[k].b==b)
return Hash[k].a;
k=Hash[k].nex;
}
return -1;
}
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return r;
}
int inval(int a,int b,int n)
{
int x,y,e;
exgcd(a,n,x,y);
e=(long long)x*b%n;
return e<0?e+n:e;
}
int powmod(long long a,int b,int c)
{
long long ret=1%c;
a%=c;
while(b)
{
if(b&1)
ret=ret*a%c;
a=a*a%c;
b>>=1;
}
return ret;
}
int babystep(int A,int B,int C)
{
top=maxn;
++idx;
long long buf=1%C,D=buf,K;
int i,d=0,tmp;
for(i=0;i<=100;buf=buf*A%C,++i)
if(buf==B)
return i;
while((tmp=gcd(A,C))!=1)
{
if(B%tmp)return -1;
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
int M=(int)ceil(sqrt((double)C));
for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)
ins(i,buf);
for(i=0,K=powmod((long long)A,M,C);i<=M;D=D*K%C,++i)
{
tmp=inval((int)D,B,C);
int w;
if(tmp>=0 && (w=find(tmp))!=-1)
return i*M+w+d;
}
return -1;
}
int main(void)
{
int A,B,C;
while(scanf("%d %d %d",&A,&C,&B),A+B+C)
{
B%=C;
int tmp=babystep(A,B,C);
if(tmp<0)
puts("No Solution");
else
printf("%d\n",tmp);
}
}