NC5929 B.Min Value(二分)
目录
Description
从 \(n\) 个数中找到两个数,使得 \(|a[i]+a[j]|\) 最小,若有多个最小值,\(i+j\) 最小优先(\(i!=j\)),输出这两个值
State
\(1<=n<=10^{5}\)
\(-10^6<=a[i]<=10^6\)
Input
5
-2
6
7
7
-8
Output
1 8
Solution
题目难的并不是该怎么解决,贪心一下就是对于 \(x\),尽量找到 \(-x\), 若 \(-x\) 不存在,那么它的前驱和后继就有可能为答案
快速寻找到 \(-x\) 的位置利用二分就可以,这里需要重写 \(lower\_bound()\) ,以位置作为第二关键字
Code
const int N = 2e5 + 5;
ll n, m, _;
int i, j, k;
struct Node
{
int c, pos;
Node(int a = 0, int b = 0):c(a), pos(b){}
}a[N];
bool cp0(Node a, Node b)
{
if(a.c == b.c) return a.pos < b.pos;
return a.c < b.c;
}
signed main()
{
//IOS;
while(~ sd(n)){
rep(i, 1, n){
sd(k);
a[i].c = k;
a[i].pos = i;
}
sort(a + 1, a + 1 + n, cp0);
pii ans = {1e9, 1e9};
rep(i, 1, n){
auto p = lower_bound(a + 1, a + 1 + n, Node(-a[i].c, a[i].pos), cp0);
if(p -> pos != a[i].pos) ans = min(ans, {abs(p -> c + a[i].c), a[i].pos + p -> pos});
auto x = p + 1, y = p - 1;
if(p != a + n && x -> pos != a[i].pos) ans = min(ans, {abs(x -> c + a[i].c), a[i].pos + x -> pos});
if(p != a + 1 && y -> pos != a[i].pos) ans = min(ans, {abs(y -> c + a[i].c), a[i].pos + y -> pos});
}
printf("%d %d\n", ans.fi, ans.se);
}
//PAUSE;
return 0;
}

浙公网安备 33010602011771号