BZOJ 3239 Discrete Logging Baby-Step-Giant-Step

题目大意:给定P,B,N,求最小的L使B^L≡N (mod P) (P是质数)

裸的BSGS。。。 练练手吧- -

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
#define INF 0x3f3f3f3f
using namespace std;
typedef pair<long long,long long> abcd;
long long A,B,C;
namespace Hash_Set{
	struct List{
		List *next;
		int key,val;
		List(List *_,int __):
			next(_),key(__),val(INF) {}
	}*head[M];
	int tim[M],T;
	inline void Clear()
	{
		++T;
	}
	int& Hash(int key)
	{
		int x=key%M;
		if(tim[x]!=T)
			tim[x]=T,head[x]=0x0;
		List *temp;
		for(temp=head[x];temp;temp=temp->next)
			if(temp->key==key)
				return temp->val;
		head[x]=new List(head[x],key);
		return head[x]->val;
	}
}
abcd EXGCD(long long x,long long y)
{
	if(!y) return abcd(1,0);
	abcd temp=EXGCD(y,x%y);
	return abcd(temp.second,temp.first-x/y*temp.second);
}
int EXBSGS()
{
	using namespace Hash_Set;
	int i;
	long long A_m,D,m=(int)ceil(sqrt(C)+1e-7);
	Clear();
	for(i=0,A_m=1;i<m;i++,(A_m*=A)%=C)
	{
		int &temp=Hash(A_m);
		temp=min(temp,i);
	}
	for(i=0,D=1;i<=m;i++,(D*=A_m)%=C)
	{
		abcd temp=EXGCD(D,C);
		long long x=(temp.first*B%C+C)%C;
		if(Hash(x)!=INF)
			return i*m+Hash(x);
	}
	return -1;
}
int main()
{
	while(cin>>C>>A>>B)
	{
		int ans=EXBSGS();
		if(!~ans) puts("no solution");
		else printf("%d\n",ans);
	}
	return 0;
}
时间: 2024-11-09 19:23:48

BZOJ 3239 Discrete Logging Baby-Step-Giant-Step的相关文章

BZOJ 3239 Discrete Logging(BSGS)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3239 [题目大意] 计算满足 Y^x ≡ Z ( mod P) 的最小非负整数 [题解] BSGS裸题. [代码] #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <tr1/unordered_map> using name

bzoj 3239: Discrete Logging【BSGS】

BSGS的板子题 此时 \( 0 \leq x \leq p-1 \) 设 \( m=\left \lceil \sqrt{p} \right \rceil ,x=i*m-j \)这里-的作用是避免逆元 于是可以把式子变形成这样:\( a^{im}\equiv ba^j(mod p) \) 枚举右边\( 0 \leq j <m \) ,用map或者hash以模数为下标来存每一个j 枚举左边\( 0 \leq i <m \) ,在map或者hash中查找对应的模数 #include<ios

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

数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)

什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSGS算法中是要求a^m在%c条件下的逆元的,如果a.c不互质根本就没有逆元.) 如果x有解,那么0<=x<C,为什么? 我们可以回忆一下欧拉定理: 对于c是素数的情况,φ(c)=c-1 那么既然我们知道a^0=1,a^φ(c)=1(在%c的条件下).那么0~φ(c)必定是一个循环节(不一定是最小的)

HDU 2815 扩展baby step giant step 算法

题目大意就是求 a^x = b(mod c) 中的x 用一般的baby step giant step 算法会超时 这里参考的是http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 map平衡树查找值 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <

【poj2417】baby step giant step

最近在学习数论,然而发现之前学的baby step giant step又忘了,于是去翻了翻以前的代码,又复习了一下. 觉得总是忘记是因为没有彻底理解啊. 注意baby step giant step只能用在b和p互质的情况下,因为只有b和p互质的情况下,b才有mod p下的逆元.(下面要用到逆元) 当b和p不互质,就要处理一下.现在就正在做这么一题,方法以后再写. 求a^(-m)就用到了求逆元了,那么如何求逆元呢?我学了两种方法: ·1:欧拉定理:当a和n互质,a^φ ( n) ≡ 1(mod

HDU 2815 Mod Tree 离散对数 扩展Baby Step Giant Step算法

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2815 题意: 思路:与上题不同,这道题不要求m是素数,是利用扩展Baby Step Giant Step算法求离散对数. 以下转载自:AekdyCoin [扩展Baby Step Giant Step] [问题模型] 求解 A^x = B (mod C) 中 0 <= x < C 的解,C 无限制(当然大小有限制--) [写在前面] 这个问题比较麻烦,目前网络上流传许多版本的做法,不过大部分已近被证明

POJ 2417/BZOJ 3239(Discrete Logging-BSGS)[Template:数论]

Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4236   Accepted: 1948 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

【BZOJ】3239: Discrete Logging

http://www.lydsy.com/JudgeOnline/problem.php?id=3239 题意:原题很清楚了= = #include <bits/stdc++.h> using namespace std; map<int, int> s; typedef long long ll; int mpow(int a, int b, int p) { a%=p; int r=1; while(b) { if(b&1) r=((ll)r*a)%p; a=((ll)