poj 2417 Discrete Logging 数论baby_step,giant_step算法

题意:

给p,b,n求最小的l使b^l==n(mod p)。

题意:

相当于在0~p-1内搜索l满足同余式,baby_step,giant_step相当于分块的二分搜索,设m=sqrt(p), 则将p分为m*m,在m块内每块进行m个数的二分搜索。

代码:

//poj 2417
//sep9
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxN=100000;
typedef long long ll;
struct Node
{
	int ids;
	ll v;
}baby[maxN];

int cmp(Node x,Node y)
{
	if(x.v!=y.v)
		return x.v<y.v;
	return x.ids<y.ids;
}
ll pow_mod(ll a,ll b,ll mod)
{
	ll ans=1;
	while(b){
		if(b&1) ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}

int bsearch(int len,ll v)
{
	int l=0,r=len,mid;
	while(l<r){
		mid=(l+r)/2;
		if(baby[mid].v==v)
			return baby[mid].ids;
		else if(baby[mid].v<v)
			l=mid+1;
		else
			r=mid;
	}
	return -1;
}

int main()
{
	ll p,b,n;
	while(scanf("%I64d%I64d%I64d",&p,&b,&n)==3){
		int m=(int)ceil(sqrt((p-1)*1.0));
		baby[0].ids=0,baby[0].v=1;
		for(int i=1;i<m;++i){
			baby[i].ids=i;
			baby[i].v=(baby[i-1].v*b)%p;
		}
		sort(baby,baby+m,cmp);
		int cnt=1;
		for(int i=1;i<m;++i)
			if(baby[i].v!=baby[i-1].v)
				baby[cnt++]=baby[i];
		ll bm=pow_mod(pow_mod(b,p-2,p),m,p);
		int ans=-1;
		for(int i=0;i<m;++i){
			int j=bsearch(cnt,n);
			if(j!=-1){
				ans=i*m+j;
				break;
			}
			n=(n*bm)%p;
		}
		if(ans<0)
			puts("no solution");
		else
			printf("%d\n",ans);
	}
	return 0;
} 
时间: 2024-11-08 06:37:04

poj 2417 Discrete Logging 数论baby_step,giant_step算法的相关文章

[poj 2417]Discrete Logging 数论 BSGS

Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3516   Accepted: 1651 Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P.

poj 2417 Discrete Logging(A^x=B(mod c),普通baby_step)

http://poj.org/problem?id=2417 A^x = B(mod C),已知A,B,C,求x. 这里C是素数,可以用普通的baby_step. 在寻找最小的x的过程中,将x设为i*M+j.从而原始变为A^M^i * A^j = B(mod C),D = A^M,那么D^i * A^j = B(mod C ), 预先将A^j存入hash表中,然后枚举i(0~M-1),根据扩展欧几里得求出A^j,再去hash表中查找相应的j,那么x = i*M+j. 确定x是否有解,就是在循环i

BSGS算法+逆元 POJ 2417 Discrete Logging

POJ 2417 Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4860   Accepted: 2211 Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarith

POJ 2417 Discrete Logging 离散对数

链接:http://poj.org/problem?id=2417 题意: 思路:求离散对数,Baby Step Giant Step算法基本应用. 以下转载自:AekdyCoin [普通Baby Step Giant Step] [问题模型] 求解 A^x = B (mod C) 中 0 <= x < C 的解,C 为素数 [思路] 我们可以做一个等价 x = i * m + j  ( 0 <= i < m, 0 <=j < m) m = Ceil ( sqrt( C

POJ 2417 Discrete Logging ( Baby step giant step )

Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3696   Accepted: 1727 Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, b

POJ 2417 Discrete Logging BSGS

Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4011   Accepted: 1849 Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, b

离散对数二连 poj 2417 Discrete Logging &amp; HDU 2815 Mod Tree

题目就不贴了.都是一样的套路求解a^x % c = b的最小x 注意HDU的题目很坑,有b比c大和题目中输出信息为全角引号的坑 下面贴的是HDU的版本,poj的改一下a,b,c顺序和输出就好 #include <iostream> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long LL; #define MOD 999

POJ 2417 Discrete Logging Baby-Step-Gaint-Step

题目大意:给出A,B,C,求A^x=B(mod C)的最小x的值. 思路:著名的BSGS算法.将C拆分成根号块,先对一个根号内的东西暴力插入一个Hash表中(别问我为什么不用map,因为这个题卡map... 另我们要求的x=i * m + j,原式可以写成A^(i * m) * A^j = B(mod C).这是ax=b(mod c)的形式我们只需要枚举i,然后看有没有符合要求的j就可以了. CODE: #define _CRT_SECURE_NO_WARNINGS #include <cmat

POJ 2417 Discrete Logging

http://www.cnblogs.com/jianglangcaijin/archive/2013/04/26/3045795.html 给p,a,b求a^n==b%p 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #include<map> 7 #define ll lon