题目描述
Alice 有 n 个正整数,数字从 1∼n 编号,分别为 a[1],a[2],…,a[n]。
Bob 刚学习取模运算,于是便拿这 n 个数进行练习,他写下了所有
a[i] mod a[j](1≤i,j≤n∧i!=j)
的值,其中 mod 表示取模运算。
Alice 想知道所有的结果中,严格次大值是多少。将取模后得到的所有值进行去重,即相同的结果数值只保留一个,剩余数中第二大的值就称为严格次大值。
输入格式
第一行一个正整数 n,表示数字个数。
第二行 n 个正整数表示 a[i]。
输出格式
仅一行一个整数表示答案。
若取模结果去重后剩余数字不足两个,则输出 −1−1。
输入输出样例
输入 #1
4 4 5 5 6
输出 #1
4
输入 #2
4 1 1 1 1
输出 #2
-1
输入 #3
7 12 3 8 5 7 20 15
输出 #3
12
说明/提示
【数据范围】
对于 40% 的数据,1≤n,a[i]≤100;
对于 70% 的数据,1≤n≤3000,1≤a[i]≤105;
对于 100% 的数据,3≤n≤2×105,1≤a[i]≤109。
【样例 1 解释】
所有取模的结果为 {4,4,4,1,0,5,1,0,5,2,1,1}。
去重后有:{0,1,2,4,5},结果为 4。
思路
由于 a mod b<a 所以最大值一定是 a[n]−1 mod a[n]
简单证明:
- 1.对于 a1到 a[n]−2 使其取模比它们大的数 就是本身 一定比 a[n]−1小
- 2.如果一个数模比它小的数 被模的数不可能是a[n] 那么最后值一定小于a[n]−1
然后我们可以想到 很明显a[n]−2 mod a[n]是所有一个数模比它大的数中次大值x
我们还要找出一个数模比它小的数中次大值 和刚才的值x比较
看起来得枚举了 其实不必
假设这个选择是a[j] mod a[i] 那么如果i≤n−2 这个值一定小于x
于是i≥n−1 只剩下一种取法:j=n,i=n−1
AC Code
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,a[300005];
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n); n=unique(a+1,a+1+n)-a-1;
a[0]=0;
if(n<=1) printf("-1");
else printf("%d",max(a[n-2],a[n]%a[n-1]));
return 0;
}