题目描述
小D今天学习了哈希,因此她对一个等比数列在模意义下的值产生了浓厚兴趣。她选定了三个数 \(n,a,p\ (0<a<p)\) ,并生成了一个共 n 项且下标从 0 开始的序列\(f_i=a^i\!\!\mod p\) 用于研究。但可惜的是,她不小心把 f 排序了一下,并且她忘记了原先的 a 的值,请你告诉她原先的 a 等于几。
注:题目描述中并没有包含部分限制条件,请仔细阅读限制与约定。
输入格式
第一行输入两个数 n,p ,表示数组长度和模数。
第二行输入 n 个数,第 i 个数为 \(f'_{i-1}\)其中序列 \(f'\)是序列 $f $排序后的内容。
输出格式
一行一个整数 a,表示原定的底数。
解析
等比数列\(a ^ 0, a ^ 1,...,a ^{ n - 1}\)中\(a ^ 1\)一定在f序列中(因为a<mod),所以我们可以枚举f序列中的每一个数,假设他是a并且判断一下。注意判断时加上另一个条件:\(a' ^ {n(n-1)/2} = a ^0 * a ^ 1 *...*a ^ {n - 1}\)。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10, inf = 1e9 + 10;
int n, p, a[N];
bool vis[N];
int qpow(int x, int k) {
int ans = 1;
while (k) {
if (k & 1) ans = 1ll * ans * x % p;
x = 1ll * x * x % p;
k >>= 1;
}
return ans;
}
bool check(int x) {
memset(vis, 0, sizeof vis);
for (int i = 1; i <= n; i ++) {
int v = qpow(x, i - 1);
int p = lower_bound(a + 1, a + n + 1, v) - a;
if (vis[p] == 1) return 0;
if (a[p] != v) return 0;
else vis[p] = 1;
}
return 1;
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> p; int mul = 1;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
mul = 1ll * mul * a[i] % p;
}
int up = 1ll * n * (n - 1) / 2;
for (int i = 1; i <= n; i ++) {
if (qpow(a[i], up) == mul) {
if (check(a[i])) {
cout << a[i] << '\n';
return 0;
}
}
}
return 0;
}
标签:int,vis,1ll,ans,序列,mul
From: https://www.cnblogs.com/YHxo/p/16786754.html