51: Luogu 2485 模板

$des$

1、给定y、z、p,计算y^z mod p 的值;

2、给定y、z、p,计算满足xy ≡z(mod p)的最小非负整数x;

3、给定y、z、p,计算满足y^x ≡z(mod p)的最小非负整数x。

$sol$

模板+模板+模板

#include <bits/stdc++.h>

using namespace std;

#define LL long long

LL n, k;

LL Ksm(LL a, LL b, LL p) {
    LL ret = 1;
    while(b) {
        if(b & 1) ret = ret * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return ret;
}

void Work1() {
    for(int i = 1; i <= n; i ++) {
        LL y, z, p; cin >> y >> z >> p;
        cout << Ksm(y, z, p) << "\n";
    }
}

LL Exgcd(LL a, LL b, LL &x, LL &y) {
    if(b == 0) {
        x = 1, y = 0; return a;
    }
    LL g = Exgcd(b, a % b, x, y);
    LL tmpx = x; x = y; y = tmpx - a / b * y;
    return g;
}

void Work2() {
    for(int i = 1; i <= n; i ++) {
        LL y, z, p; cin >> y >> z >> p;
        LL x, k;
        LL gcd = Exgcd(y, p, x, k);
        if(z % gcd) {
            puts("Orz, I cannot find x!"); continue;
        }
        LL r = z / gcd, d = p / gcd;
        x *= r;
        x = ((x % d) + d) % d;
        cout << x << "\n";
    }
}

map <LL, int> Map;

void Work3() {
    for(int i = 1; i <= n; i ++) {
        LL y, z, p; cin >> y >> z >> p;
        // y ^ x = z (mod p)
        LL m = sqrt(p);
        if(m * m != p) m ++;
        // y ^ {im} = z * y ^ j (mod p)
        if(!(y % p)) {
            puts("Orz, I cannot find x!"); continue;
        }
        Map.clear();
        Map[z % p] = 0;
        LL ans = z % p;
        for(int i = 1; i <= m; i ++) {
            ans = (ans * y) % p;
            Map[ans] = i;
        }
        LL f = Ksm(y, m, p);
        bool flag = 1;
        ans = 1;
        for(int i = 1; i <= m; i ++) {
            ans = ans * f % p;
            if(Map[ans]) {
                LL O = i * m - Map[ans];
                O = (O % p + p) % p;
                cout << O << "\n";
                flag = 0;
                break;
            }
        }
        if(flag) {
            puts("Orz, I cannot find x!");
        }
    }
} 

int main() {
    cin >> n >> k;    
    k == 1 ? Work1() : (k == 2 ? Work2() : Work3());
    
    return 0;
}

 

posted @ 2018-11-06 20:26  xayata  阅读(180)  评论(1编辑  收藏  举报