【MOBAN】卡速米,同余方程,BSGS和扩展BSGS模板

只有code,题目 前三个P2485 [SDOI2011]计算器 后一个P4195 【模板】exBSGS/Spoj3105 Mod 关于扩展bsgs,这位大佬 已经讲解地很好了。就不献丑讲解了(以前自己写的模板真的没法看orz) 卡速米,同余方程,BSGS
#include
#include
#include
#include
#include
#define int long long
using namespace std;

int T,K;
int y,z,p;
inline int mul(int x,int y)  {
    return 1ll*x*y%p;
}
inline int add(int x,int y) {
    x+=y; return x>=p?x-p:x;
}
int ksm(int a,int b) {
    int ans=1;
    for(;b;b>>=1,a=mul(a,a))
        if(b&1) ans = mul(ans,a);
    return ans;
}
int exgcd(int a,int b,int &x,int &y) {
    if(!b) {
        x=1; y=0; return a; 
    }
    int gd = exgcd(b,a%b,x,y);
    int tx = x; x = y; y = tx - (a/b)*y;
    return gd;
}
void solve1() {
    while(T--) {
        scanf("%lld%lld%lld",&y,&z,&p);
        printf("%lld\n",ksm(y,z));
    }
}
void solve2() {
    while(T--) {
        scanf("%lld%lld%lld",&y,&z,&p);
        int ox , oy;
        int d = exgcd(y,p,ox,oy);
        if(z%d) {
            puts("Orz, I cannot find x!");  continue;
        } 
        int k = z/d;
        ox = ox*k; oy = oy*k;
        y = y/d; p = p/d;
        ox%=p;
        ox = ox<0?ox+p:ox;
        printf("%lld\n",ox);
    }
}
mapma;
void solve3() {
    while(T--) {
        scanf("%lld%lld%lld",&y,&z,&p);
        y%=p; z%=p;
        if(!y)  {
            if(z==0) {
                puts("1"); continue;
            } 
            if(z==1)  {
                puts("0"); continue;
            }
            puts("Orz, I cannot find x!");
            continue;
        }
        if(z==1) {
            puts("0"); continue;
        }
        ma.clear();
        int m = ceil(sqrt(p+0.5));
        ma[z] = 0; int oy = 1;
        int  now = 1;
        for(int i=1;i<=m;i++) {
            oy = mul(oy,y);
            if(oy==z) {
                printf("%lld\n",i); goto zz;
            } else ma[mul(oy,z)] = i; 
        }

        for(int i=1;i<=m;i++) {
            now = mul(now,oy);
            if(ma.count(now)) {
                printf("%lld\n",i*m-ma[now]);
                goto zz;
            }
        }
        puts("Orz, I cannot find x!"); 
        zz:;
    }
}
main() {
    scanf("%lld%lld",&T,&K);
    if(K==1) solve1();
    else if(K==2) solve2();
    else solve3();
}
  扩展BSGS
#include
#include
#include
#include
#include
using namespace std;
typedef long long  ll;
ll a,p,b;
ll gcd(ll x,ll y) {
    return !y?x:gcd(y,x%y);
}
struct hsh {
    static const ll Ha = 999917,maxe = 200005;
    ll la[Ha+5],owo,nt[maxe];
    ll en[maxe];
    ll w[maxe],sta[maxe],top;
    void add(ll x,ll y) { if(la[x]==0)sta[++top]=x; en[++owo] = y; nt[owo] = la[x]; la[x] = owo; w[owo]=0; }
    void clear() {
        owo = 0; while(top) {la[sta[top--]] = 0;}
    }
    bool count(ll x) {
        ll o = x%Ha;
        for(ll it=la[o];it;it=nt[it]) {
            if(en[it]==x) return true;
        }
        return false;
    }
    ll &operator[] (ll x) {
        ll o = x%Ha;
        for(ll it=la[o];it;it=nt[it]) {
            if(en[it]==x) return w[it];
        }
        add(o,x); return w[owo];
    }
}ma;
void bsgs() {
    ll t=1; ll k = 0;
    ll d = gcd(a,p);
    while(d!=1) {
        if(b%d) {
            puts("No Solution"); return;
        }
        p/=d; b/=d;
        k++;
        t=t*(a/d)%p;
        if(t==b) {
            printf("%lld\n",k);  return;
        }
        d = gcd(a,p);
    }
    ma.clear();
    ma[b] = 0;
    ll oa = 1; ll oo = b;
    ll m = ceil(sqrt(p+0.5));
    for(ll i=1;i<=m;i++) {
        oa=oa*a%p; oo=oo*a%p;
        ma[oo] = i;
    }
    for(ll i=1;i<=m;i++) {
        t = t*oa%p;
        if(ma.count(t) ) {
            printf("%lld\n",i*m-ma[t]+k); return;
        }
    }
    puts("No Solution"); return;
}
int main() {
    while(233){
        scanf("%lld%lld%lld",&a,&p,&b);
        if(a+b+p==0) return 0;
        bsgs();
    }
}
   
posted @ 2018-10-22 14:46  Newuser233  阅读(8)  评论(0)    收藏  举报