BZOJ3122 BSGS

高中数学+BSGS

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll Pow(ll x,ll y,ll mod){
	ll ans=1;
	for(;y;y>>=1){
		if(y%2==1)ans=ans*x%mod;
		x=x*x%mod;	
	}
	return ans;
}
ll BSGS (ll a, ll b, ll p) {
    if (a %= p, b %= p, b == 1) return 0;
    ll t = 1; ll f, g, delta = 0, m = sqrt (p) + 1, i;
    for (g = __gcd (a, p) ; g != 1; g = __gcd (a , p) ){
        if (b % g) return -1;
        b /= g, p /= g, t = t * (a / g) % p, delta ++;
        if (b == t) return delta;
    }
    map <ll, ll> Hash;
    for (i = 0; i < m; i++, b = b * a % p) Hash [b] = i;
    for (i = 1, f = Pow (a, m, p); i <= m + 1; i++)
    if (t = t * f % p, Hash.count (t) ) return i * m - Hash [t] + delta;
    return -1;
}
int main(){
	int T;
	cin>>T;
	while(T--){
		ll p,a,b,x,t;
		cin>>p>>a>>b>>x>>t;
		if (t==x){
            printf("1\n");
            continue;
        }
        if (a==0){
            if (t==b) printf("2\n");
            else printf("-1\n");
            continue;
        }
        if (a==1&&b==0){
            printf("-1\n");
            continue;
        }
        if (a==1){
            ll nyb=Pow(b,p-2,p);
            ll ans=((((t-x)%p+p)%p)*nyb%p)%p;
            printf("%lld\n",ans+1);
            continue;
        }
		ll I=b*Pow((a+p-1)%p,p-2,p)%p;
		ll Y=(t+I)%p*Pow((x+I)%p,p-2,p)%p;
		ll ans=BSGS(a,Y,p);
		if(ans>-1)ans++;
		cout<<ans<<endl;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值