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;
}
posted @ 2021-09-09 10:02  Bcoi  阅读(30)  评论(0)    收藏  举报