洛谷U650054 三维偏序问题 题解 CDQ分治

题目链接:https://www.luogu.com.cn/problem/U650054

三维偏序问题。CDQ分治模板题。

数据范围有点大,需要先离散化一下

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5, maxm = 1e5 + 5, M = 1e5;

int n, m, id[maxn];

struct Node {
    int a, b, c, id, cnt, res;
} a[maxn];

void lsh() {
    vector<int> v;
    for (int i = 1; i <= m; i++)
        v.push_back(a[i].a);
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    for (int i = 1; i <= m; i++)
        a[i].a = lower_bound(v.begin(), v.end(), a[i].a) - v.begin() + 1;
    v.clear();
    for (int i = 1; i <= m; i++)
        v.push_back(a[i].b);
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    for (int i = 1; i <= m; i++)
        a[i].b = lower_bound(v.begin(), v.end(), a[i].b) - v.begin() + 1;
    v.clear();
    for (int i = 1; i <= m; i++)
        v.push_back(a[i].c);
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    for (int i = 1; i <= m; i++)
        a[i].c = lower_bound(v.begin(), v.end(), a[i].c) - v.begin() + 1;
}

struct BIT {
    int tr[maxm];

    int lowbit(int x) { return x & -x; }

    void add(int p, int v) {
        for (int i = p; i <= M; i += lowbit(i))
            tr[i] += v;
    }

    int query(int p) {
        int res = 0;
        for (int i = p; i; i -= lowbit(i))
            res += tr[i];
        return res;
    }

} bit;

void cdq(int l, int r) {
    if (l >= r) return;
    int mid = l + r >> 1;
    cdq(l, mid);
    cdq(mid+1, r);
    sort(a+l, a+mid+1, [](auto a, auto b) {
        return a.b < b.b;
    });
    sort(a+mid+1, a+r+1, [](auto a, auto b) {
        return a.b < b.b;
    });
    int i = l, j = mid+1;
    for (; j <= r; j++) {
        for (; i <= mid && a[i].b <= a[j].b; i++) {
            bit.add(a[i].c, a[i].cnt);
        }
        a[j].res += bit.query(a[j].c);
    }
    for (int k = l; k < i; k++)
        bit.add(a[k].c, -a[k].cnt);
}

int t[maxn];

int main() {
    scanf("%d", &n);
    map<tuple<int, int, int>, int> mp;
    for (int i = 0, a, b, c; i < n; i++) {
        scanf("%d%d%d", &a, &b, &c);
        tuple<int, int, int> tmp(a, b, c);
        id[i] = mp[tmp];
        if (!id[i]) {
            id[i] = mp[tmp] = ++m;
            ::a[ id[i] ] = {a, b, c, id[i], 1};
        }
        else
            ::a[ id[i] ].cnt++;
    }
    lsh();
    sort(a+1, a+m+1, [](auto a, auto b) {
        if (a.a != b.a) return a.a < b.a;
        if (a.b != b.b) return a.b < b.b;
        return a.c < b.c;
    });
    cdq(1, m);
    sort(a+1, a+m+1, [](auto a, auto b) {
        return a.id < b.id;
      });
    for (int i = 0; i < n; i++) {
        int _id = id[i];
        printf("%d\n", a[_id].res + a[_id].cnt - 1);
    }
    return 0;
}
posted @ 2026-01-14 22:10  quanjun  阅读(1)  评论(0)    收藏  举报