题目传送门:
CQOI2018今年到底考了多少模板题啊……
随便根据A或B求出a,b
然后照着题目说的求K就行了
高次同余一眼BSGS
然后map改成hash_map(绝对不是没有c++11编译器用不了unordered_map)
效率就很稳了
注意hash_map是非标准容器,无法直接支持long long,所以要一些黑科技
#include <bits/stdc++.h>
#include <ext/hash_map>
#define LL long long
namespace __gnu_cxx {
template<> struct hash< std::string > {
size_t operator()( const std::string& x ) const {
return hash< const char* >()( x.c_str() );
}
};
}
namespace __gnu_cxx {
template<> struct hash<long long> {
size_t operator()(long long x) const {
return (unsigned) x;
}
};
}
using namespace std;
using namespace __gnu_cxx;
template <typename T> inline void read(T &x) {
int ch = getchar();
bool fg = false;
for (x = 0; !isdigit(ch); ch = getchar()) {
if (ch == '-') {
fg = true;
}
}
for (; isdigit(ch); ch = getchar()) {
x = x * 10 + ch - '0';
}
if (fg) {
x = -x;
}
}
LL cnt;
hash_map<LL, LL> F;
LL qpow(LL a, LL b, LL c) {
LL ret = 1;
while(b) {
if(b & 1) {
ret *= a;
ret %= c;
}
b >>= 1;
a = a * a % c;
}
return ret;
}
LL BSGS(LL A, LL B, LL C) {
if(A == 0 && B == 0) {
return 1;
}
F.clear();
LL m = (LL) ceil(sqrt((double)C)); LL con = B % C , D = 1;
F[B % C] = 0;
for(LL i = 1; i <= m; i++) {
con = con * A % C;
F[con] = i;
}
con = qpow(A, m, C);
for(LL i = 1; i <= m; i++) {
D = D * con % C;
if(F[D]) {
LL t = i * m - F[D];
return (t % C + C) % C;
}
}
return 0;
}
signed main() {
LL g, P, A, B;
int n;
read(g), read(P);
read(n);
while(n --) {
read(A), read(B);
printf("%lld\n", qpow(B, BSGS(g, A, P), P));
}
return 0;
}