大家都很强, 可与之共勉。
【题目描述】
HJA在和学弟学数学,于是便有了一道非常简单的数学题:求满足 的最小自然数x。
【输入格式】
输入数据一行三个正整数a、b、p,我们保证p是一个质数。
【输出格式】
一行一个整数代表最小的自然数x,如果不存在这样的x输出-1。
【样例输入】
2 1 3
【样例输出】
0
【数据范围与规定】
对于30%的数据,1≤p≤1000。
对于100%的数据,1 ≤ a,b < p ≤ 10^12。
题解
就是一个裸的BSGS,可是考完之后才会发现爆long long……
所以恶补了一下O ( 1 ) 的快速乘。
inline long long mmul ( const long long& a, const long long& b ) {
long long lf = a * ( b >> 20 ) % p * ( 1LL << 20 ) % p ;
long long rg = a * ( b & ( ( 1LL << 20 ) - 1 ) ) % p ;
return ( lf + rg ) % p ;
}
Code :
# include <cmath>
# include <cstdio>
# include <cstring>
const long long Base = 100137 ;
struct Hash {
struct edge {
int nxt ; long long a ; int b ;
} g [Base << 4] ;
int head [Base], ecnt ;
inline void Init ( ) {
ecnt = 0 ;
memset ( head, 0, sizeof head ) ;
}
inline void insert ( long long a, int b ) {
long long key = a % Base ;
for ( register int i = head [key] ; i ; i = g [i].nxt )
if ( g [i].a == a ) return ;
g [++ ecnt] = ( edge ) { head [key], a, b } ; head [key] = ecnt ;
}
inline long long query ( long long a ) {
long long key = a % Base ;
for ( register int i = head [key] ; i ; i = g [i].nxt )
if ( g [i].a == a ) return g [i].b ;
return -1 ;
}
} hash ;
long long a, b, p ;
const long long AAA = 1LL << 20, BBB = AAA - 1 ; long long CCC ;
inline long long mmul ( const long long& a, const long long& b ) {
long long lf = a * ( b >> 20 ) % p * CCC ;
long long rg = a * ( b & BBB ) % p ;
return ( lf + rg ) % p ;
}
inline long long mpow ( register long long a, register long long x, register long long Mod ) {
register long long rt ;
for ( rt = 1 ; x ; x >>= 1, a = mmul ( a, a ) )
if ( x & 1 ) rt = mmul ( rt, a ) ;
return rt ;
}
inline long long Bsgs ( long long g, long long a, long long p ) {
hash.Init ( ) ;
int b = ( int ) ceil ( sqrt ( a ) ) ;
register long long cur = 1 ;
for ( register int i = 0 ; i < b ; ++ i, cur = mmul ( cur, g ) ) {
if ( cur == a ) return i ;
hash.insert ( cur, i ) ;
}
register long long base = mpow ( cur, p - 2, p ) ;
cur = mmul ( base, a ) ;
for ( register long long i = b ; i < p ; i += b, cur = mmul ( cur, base ) ) {
long long j = hash.query ( cur ) ;
if ( j ^ -1 ) return i + j ;
}
return -1 ;
}
int main ( ) {
freopen ( "braveheart.in", "r", stdin ) ;
freopen ( "braveheart.out", "w", stdout ) ;
scanf ( "%I64d%I64d%I64d", & a, & b, & p ) ;
CCC = AAA % p ;
return printf ( "%I64d\n", Bsgs ( a, b, p ) ), 0 ;
}