Stay Hungry,Stay Foolish!

D - ±1 Operation 2

D - ±1 Operation 2

https://atcoder.jp/contests/abc255/tasks/abc255_d

 

 

 

 

思路

首先将 A 数组进行排序,

然后计算A数组的累加数组, 即每个位置上的左侧累加值,

对于每个查询 x, 使用二分查找, 找到 upper_bound 位置, 即 0-upper_bound 位置的元素 都是 小于等于 x, upper_bound+1到末尾的的元素都是大于x的,

最后利用 累加值数组 计算 0-upper_bound 位置的元素 的总和,  与  upper_bound+1到末尾 元素的总和,

进而求解出问题解。

 

Code

#include <bits/stdc++.h>
#include <iostream>
using namespace std;
#include <limits.h>
#include <set>

/*
https://atcoder.jp/contests/abc255/tasks/abc255_d
*/

int n, q;

vector<int> a;

vector<long long> acc;

int get_upper_bound(int x) {
    if (x < a[0]) {
        return -1;
    }

    if (x > a[a.size() - 1]) {
        return a.size();
    }

    int lower = 0;
    int upper = a.size() - 1;

    while (lower < upper) {
        if (lower + 1 == upper) {
            break;
        }

        int middle = (lower + upper) / 2;

        if (x < a[middle]) {
            if (x > a[middle  - 1]) {
                return middle  - 1;
            }

            upper = middle  - 1;
        } else if (x > a[middle]) {
            if (x < a[middle + 1]) {
                return middle;
            }

            lower = middle + 1;
        } else {
            return middle;
        }
    }

//    cout << "lower = " << lower << endl;
//    cout << "upper = " << upper << endl;

    if (a[upper] == x) {
        return upper;
    } else if (a[lower] == x) {
        return lower;
    } else {
        return lower;
    }
}

long long get_diff_sum(int i, int j, int x) {
    if (i > j) {
        return 0;
    }

//    cout << "i = " << i << endl;
//    cout << "j = " << j << endl;

    long long sum = acc[j] - acc[i] + a[i];

    long long xsum = (long long)x * (j - i + 1);

//    cout << "sum = " << sum << endl;
//    cout << "xsum =" << xsum << endl;

    return abs(sum - xsum);
}

long long get_action_number(int x) {
    int upper_bound = get_upper_bound(x);
//    cout << "upper bound = " << upper_bound << endl;

    if (upper_bound == -1 || upper_bound == a.size()) {
        return get_diff_sum(0, a.size() - 1, x);
    }

    long long lower_diff_sum = get_diff_sum(0, upper_bound, x);
    long long upper_diff_sum = get_diff_sum(upper_bound + 1, a.size() - 1, x);

    return lower_diff_sum + upper_diff_sum;
}

int main() {
    cin >> n >> q;

    for (int i = 0; i < n; i++) {
        int temp;
        cin >> temp;

        a.push_back(temp);
    }

    sort(a.begin(), a.end());

    for (int i = 0; i < n; i++) {
        int temp = a[i];

        if (i == 0) {
            acc.push_back((long long)temp);
        } else {
            long long prev = acc[i - 1];
            long long curr = prev + (long long)temp;

            acc.push_back(curr);
        }
    }
//
//    vector<int>::iterator it;
//    cout << "---- a -------" << endl;
//    for (it = a.begin(); it != a.end(); it++) {
//        cout << *it << endl;
//    }
//    cout << endl;
//    cout << "---- a -------" << endl;

    for (int i = 0; i < q; i++) {
        int x;
        cin >> x;

        long long num = get_action_number(x);
        cout << num << endl;
    }

    return 0;
}

 

 
posted @ 2022-06-13 14:25  lightsong  阅读(45)  评论(0)    收藏  举报
千山鸟飞绝,万径人踪灭