POJ 3243 // HDU 2815(改下输出,加个判断)

来源:互联网 发布:萧然网络问政瓜沥 编辑:程序博客网 时间:2024/06/14 07:17
A^x = B (mod C) 的模板题,不够要用扩展BSGS

(虽然AC,但完全理解不了模板0.0,以后学好数学在来慢慢理解555555)

#include <iostream>#include <cstdio>#include <ctime>#include <cmath>const int MAXN = 1000 + 10;const int maxn = 65535;const int INF = 0x7fffffff;using namespace std;typedef long long ll;struct Hash{       ll a,b,next;}Hash[maxn << 1];ll flg[maxn + 66];ll top,idx;void ins(ll a,ll b){     ll k = b & maxn;     if (flg[k] != idx){        flg[k] = idx;        Hash[k].next = -1;        Hash[k].a = a;        Hash[k].b = b;        return ;     }     while (Hash[k].next != -1){           if(Hash[k].b == b) return ;           k = Hash[k].next;     }     Hash[k].next = ++ top;     Hash[top].next = -1;     Hash[top].a = a;     Hash[top].b = b;}ll Find(ll b){    ll k = b & maxn;    if (flg[k] != idx) return -1;    while (k != -1){          if(Hash[k].b == b) return Hash[k].a;          k = Hash[k].next;    }    return -1;}ll gcd(ll a,ll b) {return b == 0? a: gcd(b, a % b);}ll exgcd(ll a, ll b, ll &x, ll &y){    if (b == 0){x = 1; y = 0; return a;}    ll tmp = exgcd(b, a % b, y, x);    y -= x * (a / b);    return tmp;}ll solve(ll a, ll b, ll c){    ll x, y, Ans;    ll tmp = exgcd(a, c, x, y);    Ans = (ll)(x * b) % c;    return Ans >= 0 ? Ans : Ans + c;}ll pow(ll a, ll b, ll c){    ll ret = 1;    while(b)    {        if(b & 1) ret = ret * a % c;        a = a*a%c;        b>>= 1;    }    return ret;}ll BSGS(ll A, ll B, ll C){    top = maxn;    ++idx;    ll buf = 1 % C, D = buf, K, tmp;    for (ll i = 0; i <= 100; i++){        if (buf == B) return i;        buf = (buf * A) % C;    }    ll d = 0;    while ((tmp = gcd(A, C)) != 1){          if (B % tmp != 0) return -1;          d++;          B /= tmp;          C /= tmp;          D = D * A / tmp % C;    }    //hash表记录1-sqrt(c)的值    ll M = (ll)ceil(sqrt(C * 1.0));    buf = 1 % C;    for (ll i = 0; i <= M; i++){        ins(i, buf);        buf = (buf * A) % C;    }    K = pow(A, M, C);    for (ll i = 0; i <= M; i++){        tmp = solve(D, B, C);        ll w;        if (tmp >= 0 && (w = Find(tmp)) != -1) return i * M + w + d;        D = (D * K) % C;    }    return -1;}int main(){    ll A, B, C;    while (cin >> A >> C >> B && (A || B || C)){          B %= C;          ll tmp = BSGS(A, B, C); // A^x = B (mod C);          if (tmp >= 0) cout << tmp << endl;          else cout << "No Solution\n";    }    return 0;}
0 0
原创粉丝点击