P3306 [SDOI2013] 随机数生成器 BSGS+超多特判

传送门

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

unordered_map<ll, ll> mp;
ll p, a, b, x1, t;

ll bsgs(ll a, ll p, ll b) {
    
    
	mp.clear();

	if(1 % p == b % p) return 0;

	ll k = sqrt(p) + 1;

	for(ll i = 0,j = b % p; i < k; ++i, j = j * a % p) {
    
    
		mp[j] = i;
	}

	ll ak = 1;
	for(int i = 0; i < k; ++ i) ak = ak * a % p;

	for(ll i = 1, j = ak; i <= k; ++i,j = j * ak % p) {
    
    
		if(mp.count(j)) return i * k - mp[j];
	}

	return -1;
}

ll qpow(ll a, ll b) {
    
    
    ll ans = 1;
    while (b) {
    
    
        if (b & 1) ans = (ans * a) % p;
        a = (a * a) % p;
        b >>= 1;
    }
    return ans;
}

inline ll exgcd(ll a, ll b, ll & x, ll & y){
    
    
	if(b == 0){
    
    
		x = 1, y = 0;
		return a;
	}

	ll d = exgcd(b, a % b, y, x);

	y = y - (a / b) * x;

	return d;
}

ll getAns(ll a,ll b, ll m) {
    
    
	ll x, y;
	ll d = exgcd(a, m, x, y);
	if(b % d) return -2;
	return (x * (b / d) % m + m) % m;
}

int main() {
    
    
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	int T;
	cin >> T;
	while(T--) {
    
    
		cin >> p >> a >> b >> x1 >> t;
		ll res;

		if(a == 0 || a == 1 || b == 0 ) {
    
    
			if (b == 0) {
    
    
				 if(x1 == 0) {
    
    
				 	if(t == 0) cout << 1 << endl;
				 	else cout << -1 << endl;
				 	continue;
				 }
                if(a == 0) {
    
    
                    if(t == x1) {
    
    
                        cout << 1 << endl;
                    }
                    else {
    
    
                        cout << -1 << endl;
                    }

                    continue;
                }
				ll B = t * qpow(x1, p - 2) % p;
				//cout << "B:" << B << endl;
				res = bsgs(a, p, B);
			}
			else {
    
    
				if(a == 0) {
    
    
					if(x1 % p == t % p){
    
    
						cout << 1 << endl;
						continue;
					}
					if(b % p == t % p) {
    
    
						cout << 2 << endl;
						continue;
					}
					cout << -1 << endl;
					continue;
				}
				else {
    
    
					cout << getAns(b, ((t - x1) % p + p) % p, p) + 1<< endl;
					continue;
				}
			}
		}
		else {
    
    
			ll tmp = b * qpow(a - 1, p - 2);
// 			if(x1 + tmp == 0) {
    
    
// 				if(tmp == 0) cout << 1 << endl;
// 				else cout << -1 << endl;
// 				continue;
// 			}
			ll B = (t + tmp) % p * qpow(x1 + tmp, p - 2) % p;

			res = bsgs(a, p, B);
		}


		if(res == -1) {
    
    
			cout << -1 << endl;
		}
		else {
    
    
			cout << res + 1 << endl;
		}
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39602052/article/details/113278321