请问各位巨佬这题能不能用Lower_Bound(这里用二分实现)代替Map或哈希。如果不行,那么为什么?
用map是TLE了一个点,而二分却WA了7个点。随机数对拍没对出来问题,求Hack数据。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define int long long
using namespace std;
int a,p,b;
struct edge{
int num , r;
}M[1000010];
int gcd(int x,int y){
return y?gcd(y , x % y):x;
}
int ksm(int x,int y,int mod){
int temp = 1;
for(;y;y>>=1,x = x * x % mod)
if(y & 1)
temp = temp * x % mod;
return temp;
}
bool compare(edge s1,edge s2){
return s1.r < s2.r;
}
void exgcd(int A,int B,int &x,int &y){
if(B == 0){x = 1;y = 0;return ;}
exgcd(B , A % B , y , x);
y -= A / B * x;
}
int BSGS(int x,int y,int z){
int t = ceil(sqrt(z));
int ks = 1;
for(int i=1;i<=t;i++){
ks = ks * x % z;
int now = y * ks % z;
M[i].num = i;
M[i].r = now;
}
sort(M + 1 , M + 1 + t , compare);
int bkp = ksm(x , t , z);
int nxt = 1;
for(int i=1;i<=t;i++){
nxt = nxt * bkp % z;
int l = 1 , r = t , as = -1;
while(l <= r){
int mid = l + r >> 1;
if(M[mid].r == nxt){as = M[mid].num;break;}
if(M[mid].r > nxt)r = mid - 1;
else l = mid + 1;
}
if(as != -1)return ((i * t - as) % z + z) % z;
}
return -1;
}
int exBSGS(){
int sumG = 1;
int A = 1;
int k = 0;
while(true){
int g = gcd(a , p);
if(g == 1)break;
if(b % g != 0)return -1;
b /= g;
k ++;
sumG = sumG * g;
p /= g;
A = A * (a / g) % p;
if(b == A)return k;
}
int inv,sy;
exgcd(A , p , inv , sy);
inv = (inv % p + p) % p;
b = b * inv % p;
int now = BSGS(a , b , p);
if(now == -1)
return -1;
return now + k;
}
signed main(){
while(true){
cin>>a>>p>>b;
if(a == 0 && p == 0 && b == 0)break;
int ans = exBSGS();
if(ans == -1){cout<<"No Solution"<<endl;continue;}
else cout<<ans<<endl;
}
return 0;
}