前言
数论大法好,人间真善美。。。
BSGS算法
一般用来求解成立的最小的L的解
对于求解这道题,要先进行分解
设 L = i * x - y ,就得到 ,即
再移项
然后就是循环一遍 y 的值,将其存入HASH表中
在循环枚举 i ,求解出第一个满足这个式子的值就是最小值 ans = i * x - y
板题
代码
数论的东西真恶心。。
结合代码理解消化。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#define ll long long
using namespace std;
ll a , b , c , cq ;
map <ll,ll> M ;
ll ksm(ll x ) //快速幂
{
ll sum = 1 , cs = a ;
while( x > 0 ) {
if( x % 2 == 1 )
sum = ( sum * cs ) % c;
x /= 2 ;
cs = (cs*cs) % c ;
}
return sum ;
}
int main()
{
while(scanf("%lld%lld%lld", &c , &a , &b ) != EOF ) {
M.clear() ;//HASH表初始化
bool j = 0;
if( a % c == 0 ) {
printf("no solution\n");//判断是否有解
continue;
}
cq = ceil(sqrt( c ) ) ;// x 的值为 sqrt(c) 不要问我why
ll m = 0 ;
for(int i = 0 ; i <= cq ; ++ i ) {
if( i == 0 ) {
m = b % c ;
M[m] = i+1;
continue;
}
m = (m*a) % c ;
M[m] = i + 1;
}
ll q = ksm( cq ) ;
m = 1 ;
for(int i = 1 ; i <= cq ; ++ i ) {//枚举 y 的值
m = m * q % c ;
if( M[m] ) {
ll ans = i*cq-M[m]+1;//求解出 ans
j = 1 ;
printf("%lld\n", ( ans%c + c ) % c );
break;
}
}
if( !j )
printf("no solution\n");
}
return 0;
}