stack 1里面的两个点什么鬼啊
查看原帖
stack 1里面的两个点什么鬼啊
291604
王茗仟楼主2022/9/22 17:25
#define ll long long
using namespace std;


inline ll read(){
    ll x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}

ll fastpow(ll a,ll b, ll m){
    ll ans=1;
 	while(b){
		if(b&1){
			ans=ans*a%m;
		}
		a=a*a%m;
		b/=2;
	}	
    return ans;
}

ll gcd(ll a,ll b){
    if(b==0) return a;
    return gcd(b,a%b);
}


/*a的x次  同余  b(mod p)
m=ceil(sqrt(q));
i<=m;   j<m;
x=i*m-j;
a的i*m次  同余  b*a的j次(mod p)
a的i*m次  ==  a的 m次  的 i次

先算右边枚举j放入哈希,再枚举左边看看是否有解
*/

     //        2    3    5
void exbsgs(ll a,ll b,ll p){
    a%=p;b%=p;
    if(b==1||p==1){cout<<0<<endl;return;}
	if(b==a){cout<<1<<endl;return ;}
    ll cnt=0,g,k=1;
    /*将a,p转化为互质的情况*/
    while(1){
        g=gcd(a,p);
        if(g==1) break;
        if(b%g!=0){
//此情况无解与裴蜀定理相同证明
            cout<<"No Solution"<<endl;
            return ;    
        }
        cnt++;
        k=k*(a/g)%p;
    //k就是a`
        b=b/g;
        p=p/g;
        if(k==b){
    //两数相等,,x==0即可,答案为cnt;
            cout<<cnt<<endl;
            return ;
        }
    }



    ll m=ceil(sqrt(p));
    ll r=b;//右侧的数
    map<ll,ll>dict;
    dict.clear();
    dict[r]=0;
    for(int j=1;j<m;j++){
        r=r*a%p;
        dict[r]=j;
    }
    ll mi=fastpow(a,m,p);
    ll l=k;//左侧的数 ,此时的起始值,要为k就是a`
    for(int i=1;i<=m;i++){
        l=l*mi%p;
        if(dict.count(l)!=0){
            cout<<i*m-dict[l]+cnt<<endl;
            return ;
        }
    }
    cout<<"No Solution"<<endl;
    return ;
}

int main(){
    ll a,b,p;
    while(1){
        a=read();
        p=read();
        b=read();
        if(a==0&&b==0&&p==0){
            return 0;
        }
        if(b==1){cout<<0<<endl;}
        exbsgs(a,b,p);
    }
    return 0;
}


那两个点我死活过不去

2022/9/22 17:25
加载中...