您的位置:首页 > 其它

poj 2417 baby_step giant_step 高次同余方程

2017-04-15 16:53 411 查看
题解链接 :
点击打开链接

code : 

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;

const int N = (1 << 16) + 10;

struct R{
ll v, id;
bool operator < (const R &rhs) const{
return v == rhs.v ? id < rhs.id : v < rhs.v;
}
}Bj
;

ll p, b, n;

ll FastPowMod(ll a, ll b){
ll ret = 1;
while(b){
if(b & 1) ret = ret * a % p;
a = a * a % p;
b >>= 1;
}
return ret;
}

int find(int r, ll v){
int l = 0, h = r - 1;
while(l <= h){
int m = (l + h) >> 1;
if(Bj[m].v == v) return Bj[m].id;
if(Bj[m].v < v) l = m + 1;
else h = m - 1;
}
return -1;
}

int main(){
//freopen("in.txt", "r", stdin);
while(~scanf("%lld%lld%lld", &p, &b, &n)){
ll m = ceil(sqrt((double)p - 1));
for(int i = 0; i < m; ++i){
Bj[i].id = i;
Bj[i].v = i ? Bj[i - 1].v * b % p : 1;
}
sort(Bj, Bj + m);
ll pre = -1;
int cnt = 0;
for(int i = 0; i < m; ++i)
if(Bj[i].v != pre) Bj[cnt++] = Bj[i], pre = Bj[i].v;
ll tmp = FastPowMod(b, p - 1 - m);
ll R = n;
int ans = -1;
for(int i = 0; i < m; ++i){
/**if(n == 4){
printf("%lld : ", R);
for(int i = 0; i < cnt; ++i) printf("%lld、", Bj[i].v);
puts("");
}*/
int pos = find(cnt, R);
//if(n == 4) printf("%d\n", pos);
if(~pos){
ans = i * m + pos;
break;
}
R = R * tmp % p;
}
if(~ans) printf("%lld\n", ans);
else puts("no solution");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: