首页 > 其他 > 详细

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

时间:2014-02-19 16:43:07      阅读:277      评论:0      收藏:0      [点我收藏+]

不理解Baby Step Giant Step算法,请戳:

http://www.cnblogs.com/chenxiwenruo/p/3554885.html

bubuko.com,布布扣
#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;
    exgcd(a,c,x,y);
    x=((long long)x*b%c+c)%c; //注意这里要强制转换成long long,不然x*b会超出int范围
    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 一样,代码稍微改改就能AC。

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

原文:http://www.cnblogs.com/chenxiwenruo/p/3554894.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!