现在的位置: 首页 > 综合 > 正文

扩展baby step giant step模版

2018年04月26日 ⁄ 综合 ⁄ 共 1041字 ⁄ 字号 评论关闭

 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
using namespace std;
typedef __int64 LL;
LL gcd(LL a, LL b)
{
	return b ? gcd(b, a%b) : a;
}
LL pow_mod(LL a, LL p, LL n)
{
	LL ans = 1;
	while(p)
	{
		if(p&1)
		{
			ans *= a;
			ans %= n;
		}
		a *= a;
		a %= n;
		p >>= 1;
	}
	return ans;
}
void mod_gcd(LL a, LL b, LL& d, LL& x, LL& y)
{
	if(!b)
	{
		d = a;
		x = 1;
		y = 0;
	}
	else
	{
		mod_gcd(b, a%b, d, y, x);
		y -= x * (a/b);
	}
}
LL inv(LL a, LL n)
{
	LL d, x, y;
	mod_gcd(a, n, d, x, y);
	return d == 1 ? (x+n)%n : -1;
}
LL log_mod(LL a, LL b, LL n, LL c, LL d)
{
	LL m, v, e = 1, i, d2;
	m = sqrt(n+0.5);
	v = inv(pow_mod(a, m, n), n);
	d2 = inv(d, n);
	b = b*d2%n;
	map <LL, LL> x;
	x[1] = 0;
	for(i = 1; i < m; i++)
	{
		e = e*a%n;
		if(!x.count(e))
			x[e] = i;
	}
	for(i = 0; i < m; i++)
	{
		if(x.count(b))
			return c+i*m+x[b];
		b = b*v%n;
	}
	return -1;
}
LL baby(LL a, LL b, LL n)
{
	LL ans = 0, c = 0, d = 1, t;
	while((t = gcd(a, n)) != 1)
	{
		if(b%t)
		{
			ans = -1;
			break;
		}
		c++;
		n /= t;
		b /= t;
		d = d*a/t%n;
		if(d == b)
		{
			ans = c;
			break;
		}
	}

	if(ans != 0)
		return ans;
	return log_mod(a, b, n, c, d);
}
int main()
{
	LL A, B, C;
	while(scanf("%I64d %I64d %I64d", &k, &p, &n) != EOF)
	{
		if(n >= p)
		{
			puts("Orz,I can’t find D!");
			continue;
		}
		if(!n)
		{
			puts("0");
			continue;
		}
		LL ans = baby(k, n, p);
		if(ans == -1)
			puts("Orz,I can’t find D!");
		else
			printf("%I64d\n", ans);
	}
	return 0; 	
}






/*
4  164315 8192
*/

 

抱歉!评论已关闭.