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> hash;
int y,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",&y,&z,&p);
    int sec=ceil(sqrt(p)),save=z;
    for(int i=1;i<=sec;i++)
    {
        save=save*y%p;
        if(!hash[save])
            hash[save]=i;
    }
    int chk=qpow(y,sec),tmp=1;
    for(int i=1;i<=sec;i++)
    {
        tmp=tmp*chk%p;
        if(hash[chk])
        {
            printf("%d\n",i*sec-hash[tmp]);
            return 0;
        }
    }
    printf("No Answer\n");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/water-radish/p/9280575.html