码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3243 Clever Y Extended-Baby-Step-Giant-Step

时间:2017-06-27 18:43:23      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:space   puts   自己   pair   using   log   cstring   namespace   gcd   

题目大意:给定A,B,C,求最小的非负整数x,使A^x==B(%C)

传说中的EXBSGS算法0.0 卡了一天没看懂 最后硬扒各大神犇的代码才略微弄懂点0.0 

參考资料: http://quartergeek.com/bsgs/

                     http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4

这两位写的比較具体0.0 能够用于參考

对拍时发现自己代码各种脑残0.0 伤不起啊

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 1001001
using namespace std;
typedef long long ll;
typedef pair<ll,ll> abcd;
ll A,B,C,D,hash_table[M],val[M],tim[M],tot;
int Hash(ll x)
{
	int pos=x%M;
	while(1)
	{
		if(tim[pos]!=tot)
			tim[pos]=tot,hash_table[pos]=-1,val[pos]=0x3f3f3f3f;
		if(hash_table[pos]==-1||hash_table[pos]==x)
			return hash_table[pos]=x,pos;
		else
			++pos,pos%=M;
	}
}
int Get_Hash(ll x)
{
	int pos=x%M;
	while(1)
	{
		if(tim[pos]!=tot)
			tim[pos]=tot,hash_table[pos]=-1;
		if(hash_table[pos]==-1)
			return -1;
		if(hash_table[pos]==x)
			return pos;
		else
			++pos,pos%=M;
	}
}
ll GCD(ll x,ll y)
{
	return y?GCD(y,x%y):x;
}
abcd EXGCD(ll x,ll y)
{
	if(!y) return abcd(1,0);
	abcd temp=EXGCD(y,x%y);
	return abcd(temp.second,temp.first-x/y*temp.second);
}
ll Inverse(ll x)
{
	ll temp=EXGCD(x,C).first;
	return (temp%C+C)%C;
}
ll Extended_Big_Step_Giant_Step()
{
	ll i,m,cnt=0,temp,base=1;
	int pos;
	B%=C;
	for(i=0,temp=1%C;i<=50;i++,temp*=A,temp%=C)
		if(temp==B)
			return i;
	D=1;
	while(temp=GCD(A,C),temp!=1)
	{
		if(B%temp)
			return -1;
		++cnt;
		B/=temp;
		C/=temp;
		D*=A/temp;
		D%=C;
	}
	B*=Inverse(D);B%=C;
	m=(ll)ceil(sqrt(C)+1e-5);
	++tot;
	for(i=0,temp=1%C;i<m;i++,temp*=A,temp%=C)
		pos=Hash(temp),val[pos]=min(val[pos],i);
	for(i=1,base=1%C;i<=m;i++,base*=A,base%=C);
	for(i=0,D=1%C;i<m;i++,D*=base,D%=C)
	{
		temp=EXGCD(D,C).first*B;
		temp=(temp%C+C)%C;
		pos=Get_Hash(temp);
		if(~pos)
			return i*m+val[pos]+cnt;
	}
	return -1;
}
int main()
{
	memset(hash_table,0xff,sizeof hash_table);
	while(cin>>A>>C>>B,A||B||C)
	{
		ll ans=Extended_Big_Step_Giant_Step();
		if(ans==-1)
			puts("No Solution");
		else
			cout<<ans<<endl;
	}
}




POJ 3243 Clever Y Extended-Baby-Step-Giant-Step

标签:space   puts   自己   pair   using   log   cstring   namespace   gcd   

原文地址:http://www.cnblogs.com/liguangsunls/p/7086289.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!