14pts RE 求条
查看原帖
14pts RE 求条
1408977
yuyang0974楼主2025/6/12 21:53

提交记录:点这里

我的想法是:

先求出所有点相互加起来的曼哈顿距离

然后考虑夹在两条相邻x方向两条相邻y方向的所有点带来的额外贡献

求大佬帮忙看看QWQQWQ

#include<bits/stdc++.h>
using namespace std;
void read(int &x) {
    char c = getchar();
    x = 0;
    int f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -f;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + c - '0';
        c = getchar();
    }
    x = f * x;
}
int n, m, k;
const int maxn = 1e5 + 5;
const int maxk = 2e5 + 5;
const int base = 1e5 + 1;
typedef long long ll;
int a[maxn], b[maxn];
struct node {
    int x, y;
    node(int _X = 0, int _y = 0) : x(_X), y(_y) {}
    void In() {
        read(x);
        read(y);
        x += base;
        y += base;
    }
} poi[maxk];
ll ans1, ans2, ans3, ans4;
bool cmp_x(node e1, node e2) {
    return e1.x < e2.x;
}
bool cmp_y(node e1, node e2) {
    return e1.y < e2.y;
}
multiset<int> st;
multiset<int>::iterator it;
int main() {
    read(n);
    read(m);
    read(k);
    a[0] = -(base << 4);
    a[n + 1] = base << 4;
    b[0] = -(base << 4);
    b[m + 1] = base << 4;
    for(int i = 1; i <= n; i ++) {
        read(a[i]);
        a[i] += base;
    }
    for(int i = 1; i <= m; i ++) {
        read(b[i]);
        b[i] += base;
    }
    sort(a + 1, a + n + 1);
    sort(b + 1, b + m + 1);
    for(int i = 1; i <= k; i ++) poi[i].In();

    // 1. get_x
    ll sum = 0;
    sort(poi + 1, poi + k + 1, cmp_x);
    for(int i = 1; i <= k; i ++) {
        ans1 += (ll)poi[i].x * (i - 1) - sum;
        sum += poi[i].x;
    }

    // 2. get_between_heng_and_heng_is_shu
    int l = 1, r;
    for(int i = 1; i <= n + 1; i ++) {
        while(poi[l].x <= a[i - 1]) l ++;
        if(l > k) break;
        r = l - 1;
        while(r < k && poi[r + 1].x < a[i]) r ++;
        if(r == l - 1) continue;
        for(int j = l, tmp; j <= r; j ++) {
            tmp = min(poi[j].x - a[i - 1], a[i] - poi[j].x);
            st.insert(tmp);
        }
        for(int j = l, u; j <= r; j ++) {
            it = st.begin();
            u = *it;
            ans2 += ((ll)r - j) * (u << 1);
            st.erase(it);
        }
    }

    // 3. get_y
    sum = 0;
    sort(poi + 1, poi + k + 1, cmp_y);
    for(int i = 1; i <= k; i ++) {
        ans3 += (ll)poi[i].y * (i - 1) - sum;
        sum += poi[i].y;
    }

    // 4. get_between_shu_and_shu_is_heng
    l = 1;
    for(int i = 1; i <= m + 1; i ++) {
        while(poi[l].y <= b[i - 1]) l ++;
        if(l > k) break;
        r = l - 1;
        while(r < k && poi[r + 1].y < b[i]) r ++;
        if(r == l - 1) continue;
        for(int j = l, tmp; j <= r; j ++) {
            tmp = min(poi[j].y - b[i - 1], b[i] - poi[j].y);
            st.insert(tmp);
        }
        for(int j = l, u; j <= r; j ++) {
            it = st.begin();
            u = *it;
            ans4 += ((ll)r - j) * (u << 1);
            st.erase(it);
        }
    }

    // 5. output
    ll ans = ans1 + ans2 + ans3 + ans4;
    printf("%lld\n", ans);
    return 0;
}

2025/6/12 21:53
加载中...