BSGS

求解关于x的的方程\(a^x=y{\mbox{%p}}\)
证明
P2485计算器

#include <bits/stdc++.h>
#define noans cout<<"Orz, I cannot find x!\n"
using namespace std;
using ll = long long ;
const int HashMod = 100007;
ll mi(ll a,ll b,ll mod){
    ll r=1;
    while(b){
        if(1&b)r=r*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return r;
}
void _1(int n){
    while(n--){
        ll y,z,p;
        cin>>y>>z>>p;
        cout<<mi(y,z,p)<<"\n";
    }
}
void _2(int n){
    while(n--){
        ll y,z,p;
        cin>>y>>z>>p;
        ll k=z%p*mi(y,p-2,p)%p;
        if(y%p==0&&z%p) noans;
        else cout<<k<<endl;
    }
}
struct HashTable
{
    struct Line{ll u,v,next;}e[1000000];
    ll h[HashMod],cnt;
    void Add(ll u,ll v,ll w){e[++cnt]=(Line){w,v,h[u]};h[u]=cnt;}
    void Clear(){memset(h,0,sizeof(h));cnt=0;}
    void Hash(ll x,ll k)
    {
        ll s=x%HashMod;
        Add(s,k,x);
    }
    ll Query(ll x)
    {
        ll s=x%HashMod;
        for(int i=h[s];i;i=e[i].next)
            if(e[i].u==x)return e[i].v;
        return -1;
    }
}Hash;
void _3(int n){
    while(n--){
        ll y,z,p,f=0;
        cin>>y>>z>>p;
        if(y%p==0&&y%p!=z%p){noans;continue ;}///这容易被卡
        y%=p,z%=p;
        if(z==1){cout<<"0\n";continue;}
        int m=sqrt(p)+1;Hash.Clear();
        for(ll i=0,t=z;i<m;i++,t=1ll*t*y%p)Hash.Hash(t,i);
        for(ll i=1,tt=mi(y,m,p),t=tt;i<=m+1;i++,t=1ll*t*tt%p){
            ll k=Hash.Query(t);if(k==-1)continue;
            cout<<i*m-k<<"\n";
            f=1;
            break;
        }
        if(!f)noans;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int n,k;
    while(cin>>n>>k){
        switch(k){
        case 1:
            _1(n);break;
        case 2:
            _2(n);break;
        case 3:
            _3(n);break;
        }
    }
    return 0;
}
posted @ 2021-07-21 00:29  Acception  阅读(35)  评论(0)    收藏  举报