codeforces 484 B. Maximum Value (模运算+剪枝枚举)
题目链接:https://codeforces.com/problemset/problem/484/B
\[a \bmod b=a-\lfloor \frac{a}{b} \rfloor b
\]
对于 \(a\) 和 \(b(a>b)\),存在 \(k\) 使得 \(a < (k+1)b\) 且 \(a > kb\)
将 \(a\) 排序,去重,枚举 \(a[i]\) 作为 \(b\),枚举 \(a[i]\) 的倍数
这里有一个剪枝,倒序枚举 \(b\),如果当前枚举的 \(b \le ans\) 时,就跳过后面的 \(b\)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 200010;
int n;
int a[maxn];
int find(int x){
int res = -1;
int l = 1, r = n;
while(l <= r){
int mid = (l+r) >> 1;
if(a[mid] < x){
res = mid;
l = mid+1;
} else{
r = mid-1;
}
}
return res;
}
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
n = read();
for(int i = 1 ; i <= n ; ++i) a[i] = read();
sort(a+1, a+1+n);
int q = unique(a+1, a+1+n)-a-1;
int ans = 0;
for(int i = q ; i >= 1 ; --i) {
if(a[i] <= ans) continue;
for(int k = 1 ; k*a[i] <= a[q] ; ++k){
int pos = find((k+1)*a[i]);
ans = max(ans, a[pos] - k*a[i]);
}
}
printf("%d\n", ans);
return 0;
}