您的位置:首页 > 其它

POJ 3243 Clever Y (求解高次同余方程A^x=B(mod C) Baby Step Giant Step算法)

2014-02-18 21:01 465 查看
不理解Baby Step Giant Step算法,请戳:

/article/6436994.html

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define SIZE 99991
/*
POJ 3243
AC
求解同余方程:
A^x=B(mod C)
*/
using namespace std;
struct HashTable{
int key[SIZE];  //对应A^i
int val[SIZE];  //对应i
void init(){
memset(key,-1,sizeof(key));
memset(val,-1,sizeof(val));
}
int hfind(int k){
int kk=k%SIZE;
while(key[kk]!=k && key[kk]!=-1){
kk=(kk+1)%SIZE; //原先写成了kk=(kk+1)&SIZE;导致一直TLE。。。
}
return val[kk];
}
void hinsert(int v,int k){
int kk=k%SIZE;
while(key[kk]!=-1 && key[kk]!=k){
kk=(kk+1)%SIZE;
}
if(key[kk]==-1){
key[kk]=k;
val[kk]=v;
}
}
}h;

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==0){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int tmp=x;
x=y;
y=tmp-a/b*y;
return d;
}

//求解ax=b(mod c),
int solvex(int a,int b,int c){
int x,y;
int d;
d=exgcd(a,c,x,y);
//注意这里要强制转换成long long,不然x*b会超出int范围
x=((long long)x*b%c+c)%c;
//x=((long long)x*(b/d)%(c/d)+c/d)%(c/d); //实际应该是这样,但由于传的参数D,B,C中,D、C互质,d=1。
return x;
}
long long quickPow(long long a,int b,int mod){
long long ret=1%mod;
a=a%mod;
while(b){
if(b&1)
ret=(ret*a)%mod;
a=(a*a)%mod;
b=b>>1;
}
return ret;
}
int BabyStep(int A,int B,int C){
B=B%C;  //注意这里先要将B对C取模
h.init();
int d=0;
long long D=1%C,buf=D;
for(int i=0;i<=100;buf=buf*A%C,++i){
if(buf==B)
return i;
}
int tmp;
while((tmp=gcd(A,C))!=1){
if(B%tmp)
return -1;
d++;
B=B/tmp;
C=C/tmp;
D=D*A/tmp%C;
}
int m=(int)ceil(sqrt((double)C));
buf=1%C;
for(int i=0;i<m;buf=buf*A%C,++i){
h.hinsert(i,(int)buf);
}
long long K=quickPow((long long)A,m,C);
for(int i=0;i<m;D=D*K%C,++i){
int ans=solvex((int)D,B,C);
int j=h.hfind(ans);
if(j!=-1)
return i*m+j+d;
}
return -1;
}
int main()
{
int A,B,C;
while(scanf("%d%d%d",&A,&C,&B)!=EOF){
if(A==0 && B==0 && C==0)
break;
int ans=BabyStep(A,B,C);
if(ans==-1)
printf("No Solution\n");
else
printf("%d\n",ans);
}
return 0;
}


View Code

该题和POJ 2417,HDU 2815 一样,代码稍微改改就能AC。

不过不同的是,HDU 2815 若B>=C,则要判断无解。而不是像POJ这两道题,要先B%C一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: