poj 2417 baby_step giant_step 高次同余方程

题解链接 : 点击打开链接


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[N];

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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值