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;
}
posted @ 2021-09-10 15:06  Tartarus_li  阅读(79)  评论(0编辑  收藏  举报