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 <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

long long A,B,C;

void EXGCD(long long a,long long b,long long &d,long long &x,long long &y)
{
	if(!b) {
		d = a,x = 1,y = 0;
		return ;
	}
	EXGCD(b,a % b,d,y,x);
	y -= x * (a / b);
}

long long Solve(long long a,long long b,long long c)	//ax = b(mod c)
{
	long long x = 0,y = 0,d = 0;
	EXGCD(a,c,d,x,y);
	return ((x % c) + c) * b % c;
}

long long QuickPower(long long x,long long y)
{
	long long re = 1;
	while(y) {
		if(y&1)	re = re * x % C;
		x = x * x % C;
		y >>= 1;
	}
	return re;
}

struct HashSet{
#define MO 23333
	int head[MO * 2 + 10],total;
	int next[MO * 2 + 10],f[MO * 2 + 10];
	long long val[MO * 2 + 10];

	void Reset() {
		memset(head,0,sizeof(head));
		total = 0;
	}
	void Insert(long long x,int _) {
		int temp = x % MO;
		for(int i = head[temp]; i; i = next[i])
			if(val[i] == x) {
				f[i] = min(f[i],_);
				return ;
			}
		next[++total] = head[temp];
		val[total] = x;
		f[total] = _;
		head[temp] = total;
	}
	int Find(long long x) {
		int temp = x % MO;
		for(int i = head[temp]; i; i = next[i])
			if(val[i] == x)
				return f[i];
		return -1;
	}
}G;

int main()
{
	while(scanf("%I64d%I64d%I64d",&C,&A,&B) != EOF) {
		G.Reset();
		long long temp = 1,m = ceil(sqrt((double)C));
		for(int i = 0; i < m; ++i) {
			G.Insert(temp,i);
			temp = temp * A % C;
		}
		bool find = false;
		for(int i = 0; i * m < C; ++i) {
			long long temp = Solve(QuickPower(A,i * m),B,C);
			if(G.Find(temp) != -1) {
				printf("%I64d\n",i * m + G.Find(temp));
				find = true;
				break;
			}
		}
		if(!find)	puts("no solution");
	}
	return 0;
}

时间: 2024-08-29 12:33:41

POJ 2417 Discrete Logging Baby-Step-Gaint-Step的相关文章

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 离散对数

链接: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

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(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

[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 数论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 ma

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

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