洛谷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;
}
浙公网安备 33010602011771号