树状数组、离散化、二维偏序
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <utility>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
struct Item {
int a, b, c;
int id;
int ans;
explicit Item(int _a = 0, int _b = 0, int _c = 0) : a(_a), b(_b), c(_c) {}
};
struct cmpa {
bool operator()(const Item &lhs, const Item &rhs) const {
return lhs.a > rhs.a || (lhs.a == rhs.a && lhs.b < rhs.b)
|| (lhs.a == rhs.a && lhs.b == rhs.b && lhs.c < rhs.c);
}
};
struct cmpc {
bool operator()(const Item &lhs, const Item &rhs) const {
return lhs.c > rhs.c || (lhs.c == rhs.c && lhs.b < rhs.b)
|| (lhs.c == rhs.c && lhs.b == rhs.b && lhs.a < rhs.a);
}
};
priority_queue<Item, vector<Item>, cmpa> Qin;
priority_queue<Item, vector<Item>, cmpc> Qout;
const int MAXN = 300100;
int ca[MAXN];
int lsh[MAXN], lsc;
Item za[MAXN];
unordered_map<int, int> lss;
void addZ(int x, int v) {
while (x <= lsc) {
ca[x] += v;
x += (x & -x);
}
}
int getZ(int x) {
int ans = 0;
while (x) {
ans += ca[x];
x -= (x & -x);
}
return ans;
}
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d%d%d", &za[i].a, &za[i].b, &za[i].c);
Qin.push(za[i]);
lsh[lsc++] = za[i].a;
lsh[lsc++] = za[i].b;
lsh[lsc++] = za[i].c;
za[i].id = i;
}
sort(lsh, lsh + lsc);
lsc = unique(lsh, lsh + lsc) - lsh;
for (int i = 0; i < lsc; ++i) {
lss[lsh[i]] = i + 1;///离散化
}
sort(za, za + n, [](const Item &a, const Item &b) { return a.b < b.b; });
for (int i = 0; i < n; ++i) {
while (!Qin.empty()) {
Item xx = Qin.top();
if (za[i].b > xx.a) {
Qin.pop();
addZ(lss[xx.b], 1);
Qout.push(xx);
} else break;
}
while (!Qout.empty()) {
Item xx = Qout.top();
if (za[i].b >= xx.c) {
Qout.pop();
addZ(lss[xx.b], -1);
} else break;
}
za[i].ans = getZ(lss[za[i].c]) - getZ(lss[za[i].a]);
}
sort(za, za + n, [](const Item &a, const Item &b) { return a.id < b.id; });
for (int i = 0; i < n; ++i)printf("%d\n", za[i].ans-1);
return 0;
}