1. 程式人生 > >【Ex_BSGS&BSGS演算法模板】poj2417 poj3243

【Ex_BSGS&BSGS演算法模板】poj2417 poj3243

題意:給定a,b,p,求最小的非負整數x,滿足  ax ≡ b(mod p)
Ex_BSGS,p是不是素數都可以

//#include <bits/stdc++.h>
///複雜度為O(sqrt(n))
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define X 10005
#define inF 0x3f3f3f3f
#define PI 3.141592653589793238462643383
#define IO  ios::sync_with_stdio(false),cin.tie(0), cout.tie(0);
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
typedef unsigned long long Ull; //2^64
const int maxn = (int)2*1e7 + 10;
const int MOD = 9973;//(int)1e9 + 7;
const ll inf = 9223372036854775807;
const int mod=76532;
ll hs[mod],id[mod],head[mod],next[mod],top;
void Insert(ll x,ll y)
{int k=x%mod;
 hs[top]=x,id[top]=y,next[top]=head[k],head[k]=top++;
}
ll Find(ll x)
{
    int k=x%mod;
    for(int i=head[k];i!=-1;i=next[i])
        if(hs[i]==x)return id[i];
    return -1;
}
ll BSGS(ll a,ll b,ll n) // a^x ≡ b mod n    n是不是素數都可以
{                      // a^im ≡ b*a^j mod n 1<= i <=m 0<= j <=m
    memset(head,-1,sizeof(head));
    top=1;
    if(b==1)return 0;
    ll m=sqrt(n*1.0),x=1,p=1,j;
    for(int j=0;j<m;++j,p=p*a%n) Insert(p*b%n,j);
    for(ll i=m; ;i+=m)
    {
        if( ( j=Find(x=x*p%n)) !=-1) return i-j;
        if(i>n)break;
    }
    return -1;
}
int main()
{
    ll a,b,p;
    while(scanf("%lld%lld%lld",&p,&a,&b)!=EOF)
    {
        ll d=BSGS(a,b,p);
        if(d==-1)
            cout<<"no solution"<<endl;
        else
            cout<<d<<endl;
    }
    return 0;
}

 X^Y mod Z = K   
 優化的BSGS演算法 使得 Z不是素數的時候可以求出最小的 y 使得同餘式成立

 

//#include <bits/stdc++.h>
///複雜度為O(sqrt(n))
#include <iostream>//XY mod Z = K 模板題
#include <cstring>
#include <cstdio>
#include <cmath>
#define X 10005
#define inF 0x3f3f3f3f
#define PI 3.141592653589793238462643383
#define IO  ios::sync_with_stdio(false),cin.tie(0), cout.tie(0);
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
typedef unsigned long long Ull; //2^64
const int maxn = (int)1e5 + 10;
const int MOD = 9973;//(int)1e9 + 7;
const ll inf = 9223372036854775807;
const int mod = (int)1e5 + 10;
ll hs[mod],next[mod],head[mod],id[mod],top;
void insert(ll x,int y)
{
    int k=x%mod;
    hs[top]=x,id[top]=y,next[top]=head[k],head[k]=top++;
}
ll find(ll x)
{
    int k=x%mod;
    for(int i=head[k];i!=-1;i=next[i])
    {
        if(hs[i]==x)return id[i];
    }
    return -1;
}
ll BSGS(ll a,ll b,ll n)
{
    memset(head,-1,sizeof(head));
    if(b==1)return 0;
    top=1;
    ll m=sqrt(n*1.0),x=1,j,p=1;
    for(int i=0;i<m;++i,p=p*a%n) insert(p*b%n,i);
    for(ll i=m; ;i+=m)
    {
        if((j=find(x=x*p%n))!=-1)return i-j;
        if(i>n)break;
    }
    return -1;
}
int main()
{
    ll x,z,k;
    while(scanf("%lld%lld%lld",&x,&z,&k)&&(x||z||k))
    {
        ll d=BSGS(x,k,z);
        if(d==-1)
            cout<<"No Solution"<<endl;
        else
            cout<<d<<endl;
    }
    return 0;
}
/*