zoukankan      html  css  js  c++  java
  • POJ 3243 Clever Y Extended-Baby-Step-Giant-Step

    题目大意:给定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;
    	}
    }




  • 相关阅读:
    并查集
    关于一些位运算的小记
    用ST解决RMQ问题
    寒假作业_4
    H
    卢卡斯 组合数
    并查集
    G
    F
    E
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7086289.html
Copyright © 2011-2022 走看看