Description
你还记得[NOI2012]随机数据生成器这道题吗。
这道题呢,就是让你求他生成出来的这个数C是第几项。
Sample Input
3
7 1 1 3 3
7 2 2 2 0
7 2 2 2 1
Sample Output
1
3
-1
这道题真可谓是全新版本,推一下式子即可。
f
[
n
]
=
a
n
−
1
∗
X
1
+
b
∗
(
a
0
+
a
1
+
.
.
.
+
a
n
−
2
)
f[n]=a^{n-1}*X1+b*(a^0+a^1+...+a^{n-2})
f[n]=an−1∗X1+b∗(a0+a1+...+an−2)
等比公式搞一下。
f
[
n
]
=
a
n
−
1
∗
X
1
+
b
∗
(
a
n
−
1
−
1
)
/
(
a
−
1
)
f[n]=a^{n-1}*X1+b*(a^{n-1}-1)/(a-1)
f[n]=an−1∗X1+b∗(an−1−1)/(a−1)
和一下
f
[
n
]
=
a
n
−
1
∗
X
1
∗
(
a
−
1
)
/
(
a
−
1
)
+
b
∗
(
a
n
−
1
−
1
)
/
(
a
−
1
)
f[n]=a^{n-1}*X1*(a-1)/(a-1)+b*(a^{n-1}-1)/(a-1)
f[n]=an−1∗X1∗(a−1)/(a−1)+b∗(an−1−1)/(a−1)
f
[
n
]
=
(
a
n
−
1
∗
X
1
∗
(
a
−
1
)
+
(
b
∗
a
n
−
1
)
)
/
(
a
−
1
)
−
b
/
(
a
−
1
)
f[n]=(a^{n-1}*X1*(a-1)+(b*a^{n-1}))/(a-1)-b/(a-1)
f[n]=(an−1∗X1∗(a−1)+(b∗an−1))/(a−1)−b/(a−1)
移过去
f
[
n
]
∗
(
a
−
1
)
+
b
=
a
n
−
1
∗
(
X
1
∗
(
a
−
1
)
+
b
)
f[n]*(a-1)+b=a^{n-1}*(X1*(a-1)+b)
f[n]∗(a−1)+b=an−1∗(X1∗(a−1)+b)
然后解BSGS即可,
有几种特殊情况,比如a=0,a=1,特判一下。
其他没什么好说的。。。
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL Mod = 1000007;
LL mod, cnt;
LL head[1100000], next[1100000], num[1100000];
LL exgcd(LL a, LL b, LL &x, LL &y) {
if(b == 0) {x = 1, y = 0; return a;}
else {
LL tx, ty, d = exgcd(b, a % b, tx, ty);
x = ty, y = tx - ty * (a / b);
return d;
}
}
LL pow_mod(LL a, LL k) {
LL ans = 1; a %= mod;
while(k) {
if(k & 1) ans = ans * a % mod;
a = a * a % mod; k /= 2;
} return ans;
}
LL BSGS(LL a, LL b) {
LL t = sqrt(mod) + 1, u = 1;
for(int i = 1; i <= t; i++) {
num[i] = u * b % mod;
LL y = num[i] % Mod;
if(!head[y]) head[y] = i;
else {
int o = head[y];
bool bk = 0;
while(next[o]) {
if(num[i] == num[o]) {bk = 1; break;}
o = next[o];
} if(!bk) next[o] = i;
} u = u * a % mod;
} a = u; u = 1;
if(a == 0) {
if(b == 0) return 1;
return -2;
}
for(int i = 0; i < t; i++) {
LL y = u % Mod;
int o = head[y];
while(num[o] != u && o) o = next[o];
if(num[o] == u) {
int j = o - 1;
if(i * t - j >= 0) return i * t - j;
} u = u * a % mod;
} return -2;
}
int main() {
int tt; scanf("%d", &tt);
while(tt--) {
LL a, b, X1, c;
scanf("%lld%lld%lld%lld%lld", &mod, &a, &b, &X1, &c);
if(c == X1) {printf("1\n"); continue;}
if(a == 0) {
if(b != c) printf("-1\n");
else printf("2\n");
continue;
}
if(a == 1) {
c = ((c - X1) % mod + mod) % mod;
LL x, y, d = exgcd(b, mod, x, y);
if(c % d != 0) {printf("-1\n"); continue;}
x = (x * (c / d) % (mod / d) + (mod / d)) % (mod / d);
printf("%lld\n", x + 1);
continue;
}
c = c * (a - 1) % mod;
c = (c + b) % mod;
c = c * pow_mod((X1 * (a - 1) % mod + b), mod - 2) % mod;
memset(next, 0, sizeof(next));
memset(head, 0, sizeof(head));
memset(num, 0, sizeof(num));
printf("%lld\n", BSGS(a, c) + 1);
}
return 0;
}