BSGS 大步小步算法

//大步小步算法 BSGS 
//对于式子 x^y=z mod p 已知x,z和p可求y 
//由于费马小定理 y的取值范围为[0,p-1] 
//利用分块思想 将y分为a*m+b m=sqrt(p-1) 
//其中x^b预处理存在Hash中 枚举a即可 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
map<int,int> hsh;
int x,z,p;
int qpow(int x,int y)
{
    int ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%p;
        x=x*x%p;
        y/=2;
    }
    return ans;
}
int main()
{
    scanf("%d%d%d",&x,&z,&p);
    int sec=ceil(sqrt(p)),save=z;
    for(int i=1;i<=sec;i++)
    {
        save=save*x%p;
        if(!hsh[save])
            hsh[save]=i;
    }
    int chk=qpow(x,sec),tmp=1;
    for(int i=1;i<=sec;i++)
    {
        tmp=tmp*chk%p;
        if(hsh[tmp])
        {
            printf("%d\n",i*sec-hsh[tmp]);
            return 0;
        }
    }
    printf("No Answer\n");
    return 0;
}

 

posted @ 2018-07-08 17:08  radishえらい  阅读(241)  评论(0编辑  收藏  举报