考虑以下用于生成伪随机排列的 C++ 代码:
long long x, a, b, p;
int n;
long long rand() {
x = ((__int128)x * a + b) % p;
return x;
}
int main() {
cin >> n;
cin >> x >> a >> b >> p;
for (int i = 1; i <= n; i++) { //random shuffle [1, 2,..., n]
perm[i] = i;
swap(perm[i], perm[rand() % i + 1]);
}
for (int i = 1; i <= n; i++) { //print the result
cout << perm[i] << (i == n ? '\n' : ' ');
}
}
给定 $n, a, b, p$ 以及输出的排列 $perm_1, perm_2, \dots, perm_n$,求 $x$ ($0 \le x < p$)。
输入格式
第一行包含 $n$ ($n = 10^5$)。
第二行包含 $perm_1, perm_2, \dots, perm_n$ ($1 \le perm_i \le n$)。
第三行包含 $a, b, p$ ($2 \le a < p, 0 \le b < p, 500 \le p \le 10^{16}$)。$p$ 为质数,$a, b, x$ 均在各自范围内均匀随机选择。
输出格式
一个整数 $x$。如果存在多个解,输出任意一个即可。
样例
输入 1
100000 38898 35776 38192 80605 84959 ... 356846063 184710711 911417497 (truncated)
输出 1
681779867
说明
完整的样例测试数据可在竞赛系统中作为附件下载。