题解 P4028 【New Product】

· · 题解

一道比较裸的BSGS

但事实上,这个题有一堆坑点。以下就列举一下:

在对式子A^k \equiv B(\mod P~~) 进行BSGS时,

    P = ceil(sqrt(p)), Q = expow(x, -P + 2 *(p - 1), p) ;

剩下的大概就没啦~

#include <cmath>
#include <cstdio>
#include <iostream>
#include<tr1/unordered_map>

#define LL long long

using namespace std ; 
using namespace tr1 ; int T ;
LL A, B, M, P, Q ; unordered_map <LL, LL> Hash ;

inline LL expow(LL a, LL b, LL p){
    LL res = 1 ;
    while (b){
        if (b & 1) 
            (res *= a) %= p ;
        (a *= a) %= p, b >>= 1 ;
    }
    return res % p ;
}
inline void bsgs(LL x, LL y, LL p){
    P = ceil(sqrt(p)), Hash.clear(), Q = expow(x, -P + 2 *(p - 1), p) ;
    //a ^ (p-1) = 1 (mod p) => Q = a^(-P) = a ^(-P + p -1) ;
    for (LL i = 1, j = 0 ; j < P ; ++ j, (i *= x) %= p) 
        if (!Hash.count(i)) Hash[i] = j ; // Push them into hash_table
    for (LL i = y, j = 0  ; j <= P ; ++ j, (i *= Q) %= p) 
        if (Hash.count(i)){ cout << Hash[i] + j * P << endl ; return ; }
    cout << "Couldn't Produce!" << endl ;
}
inline LL qr(){
    LL res = 0 ; char c = getchar() ; while (!isdigit(c)) c = getchar() ;
    while (isdigit(c)) res = (res << 1) + (res << 3) + c - 48, c = getchar() ;
    return res ;
}
int main(){
    cin >> T ;
    while (T --){
        M = qr(), A = qr(), B = qr() ;
        if ((!(A % M == 0 && B))) bsgs(A, B, M) ;
        else cout << "Couldn't Produce!" << endl ; 
    }
    return 0 ;
}