bzoj3122 [SDOI2013]随机数生成器
bzoj3122 [SDOI2013]隨機(jī)數(shù)生成器
給定一個(gè)遞推式, \(X_i=(aX_{i-1}+b)\mod P\)
求滿足 \(X_k=t\) 的最小整數(shù)解,無(wú)解輸出 \(-1\)
\(0\leq a,\ b,\ t,\ P\leq10^9,\ P\) 為質(zhì)數(shù)
BSGS
首先化式子,推得
\[X_k=a^{k-1}x+b\displaystyle\sum_{i=0}^{k-2}a_i\]
因此
\[\begin{aligned}\displaystyle\sum_{i=0}^{k-2}a_i&\equiv\frac{t-a^{k-1}x}{b}\pmod P\\\frac{a^{k-1}-1}{a-1}&\equiv\frac{t-a^{k-1}x}{b}\pmod P\\a^{k-1}(b-x+ax)&\equiv at-t+b\pmod P\\a^{k-1}&\equiv\frac{at-t+b}{b-x+ax}\pmod P\end{aligned}\]
所以上 \(BSGS\)
然而這題特判很惡心,不加特判 \(0\text{pts}\)
特判如下:
- \(x=t:ans=1\)
- \(a=1\)
- \(b=0:ans=-1\)
- \(b\neq0:ans=\frac{t-x}{b}+1\)
- \(a=0\)
- \(b=t:ans=2\)
- \(b\neq t:ans=-1\)
時(shí)間復(fù)雜度 \(O(T\sqrt P)\)
代碼
#include <bits/stdc++.h> using namespace std;int P;int qp(int a, int k) {int res = bool(a);for (; k; k >>= 1, a = 1ll * a * a % P) {if (k & 1) res = 1ll * res * a % P;}return res % P; }int bsgs(int a, int b) {if (!a && b) return -1;map <int, int> s;int sz = sqrt(P), inv_a = qp(a, P - 2), pw = qp(a, sz), cur = 1;for (int i = 0; i <= sz; i++) {s.insert(make_pair(1ll * b * cur % P, i)), cur = 1ll * cur * inv_a % P;}cur = 1;map <int, int> :: iterator it;for (int i = 0; i <= sz; i++, cur = 1ll * cur * pw % P) {if ((it = s.find(cur)) != s.end()) {return i * sz + (it -> second);}}return -1; }int main() {int Tests, a, b, x, t, A, B;scanf("%d", &Tests);while (Tests--) {scanf("%d %d %d %d %d", &P, &a, &b, &x, &t);a %= P, b %= P, x %= P, t %= P;if (x == t) {puts("1"); continue;} else if (a == 1) {if (!b) {puts("-1"); continue;}printf("%d\n", 1ll * (t - x + P) * qp(b, P - 2) % P + 1);continue;} else if (!a) {puts(b == t ? "2" : "-1");continue;}A = a, B = 1ll * (1ll * a * t - t + b + P) % P * qp((b - x + 1ll * a * x + P) % P, P - 2) % P;int ans = bsgs(A, B);printf("%d\n", ~ans ? ans + 1 : ans);}return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/Juanzhang/p/10659176.html
總結(jié)
以上是生活随笔為你收集整理的bzoj3122 [SDOI2013]随机数生成器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Apache 服务器存在高危提权漏洞,请
- 下一篇: 架构漫谈(1):什么是架构