POJ - 3243 Clever Y

Solution

\(POJ\) 跑的太快了!

我们用 \(hash\) 优化。选择一个让你心动的模数,把它像前向星一样存起来就行了。

Code

//#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
typedef long long ll;
//using namespace std;
//#if(__cplusplus == 201103L)
//#include <unordered_map>
//#else
//#include <tr1/unordered_map>
//namespace std {using std::tr1::unordered_map;}
//#endif

const int p = 1e7, N = 1e5;

//map <int, int> mp;
int mod, a, b, ans;
int cnt, head[p], from[N], to[N], nxt[N];

int read() {
    int x = 0, f = 1; char s;
    while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
    while(s >= '0' && s <= '9') x = (x << 1) + (x << 3) + (s ^ 48), s = getchar();
    return x * f;
}

int gcd(const int x, const int y) {return !y ? x : gcd(y, x % y);}

int qkpow(int x, int y) {
    int r = 1;
    while(y) {
        if(y & 1) r = 1ll * r * x % mod;
        x = 1ll * x * x % mod; y >>= 1;
    }
    return r;
}

void Insert(const int x, const int y) {
    int k = x % p; ++ cnt;
    from[cnt] = x, to[cnt] = y;
    nxt[cnt] = head[k], head[k] = cnt;
}

int Find(const int x) {
    int k = x % p;
    for(int i = head[k]; ~i; i = nxt[i])
        if(from[i] == x) return to[i];
    return -1;
}

int exBSGS() {
    if(b == 1) return 0;
    if(a % mod == 0) return 0;
    //mp.clear();
    memset(head, -1, sizeof head); cnt = 0;
    int cnt = 0, t = 1, s, x, m;
    for(int d = gcd(a, mod); d != 1; d = gcd(a, mod)) {
        if(b % d) return -1;
        ++ cnt; b /= d, mod /= d; t = 1ll * t * a / d % mod;
        if(b == t) return cnt;
    }
    s = b, m = ceil(sqrt(mod));
    for(int i = 0; i <= m; ++ i) Insert(s, i), s = 1ll * s * a % mod;
    x = qkpow(a, m), s = t;
    for(int i = 1; i <= m; ++ i) {
        s = 1ll * s * x % mod;
        int r = Find(s);
        if(r != -1) return i * m - r + cnt;
    }
    return -1;
}

int main() {
    while(1) {
        a = read(), mod = read(), b = read();
        if(a + mod + b == 0) break;
        a %= mod, b %= mod;
        ans = exBSGS();
        if(ans < 0) puts("No Solution");
        else printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AWhiteWall/p/12981119.html
y
今日推荐