bsgs BSGS

Question:
had known a,b,c;
ask min x;
to made a^x=b(mod c);

think:
make m=ceil(sqrt(c));
make x=i*m-j;
so a^(i*m-j)=b(mod c)
so a^(i*m)/a^j=b(mod c)
so a^(i*m)=b*a^j(mod c)

easy to meijv i,j to full this deng shi

ANS:

answer=min(i*m-j);

 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#define ll longlong
#define readln(n) scanf("%lld",&n);
#define writeln(n) printf("%lld",n);

using namespace std;

map<ll,int>mp;

inline ll f(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}

int main()
{
    ll n;//a^x=b(mod)c,a^(i*m)=b*(a^j)(mod)
    readln(n);
    ll a,b,c;
    readln(a);readln(b);readln(c);
    if(!a%c){printf("!!!"); return 0; }
    ll m=ceil(sqrt(c));
    ll ans=b%c;
    mp[ans]=0;
    for(int i=1;i<=m;i++)
    {
        asn=(ans*a)%c;
        mp[ans]=i;
    }
    ll ff=f(a,m,c);
    ans=1;
    bool flag=1;
    for(int i=1;i<=m;i++)
    {
        ans=ans*f%c;
        if(mp[ans])
        {
            ll answer=i*m-mp[ans];
            writeln((answer%c+c)%c);
            flag=0;
        } 
    }
    if(!flag)
    printf("!!!");
}

 

posted @ 2017-05-19 19:19  ioioioioioio  阅读(160)  评论(0编辑  收藏  举报