“`cpp
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct TArray {
int c[1000010], mn;
void update(int n, int dt) {
while (n <= mn) {
c[n] += dt;
n += n & (-n);
}
}
int query(int n) {
int ans = 0;
while (n > 0) {
ans += c[n];
n -= n & (-n);
}
return ans;
}
};
struct Val {
int a, b, c, ctr, ans;
const bool operator==(Val& rhs) {
if (a != rhs.a) { return false; }
if (b != rhs.b) { return false; }
if (c != rhs.c) { return false; }
return true;
}
};
bool comp(Val& lhs, Val& rhs) {
if (lhs.a != rhs.a) { return lhs.a < rhs.a; }
if (lhs.b != rhs.b) { return lhs.b < rhs.b; }
if (lhs.c != rhs.c) { return lhs.c < rhs.c; }
return false;
}
bool _comp(Val& lhs, Val& rhs) {
if (lhs.b != rhs.b) { return lhs.b < rhs.b; }
if (lhs.c != rhs.c) { return lhs.c < rhs.c; }
if (lhs.a != rhs.a) { return lhs.a < rhs.a; }
return false;
}
int n, k, t = 0, b[100010];
Val v[100010], a[100010];
TArray ta;
void cdq(int l, int r) {
if (l == r) {
a[l].ans += a[l].ctr – 1;
return;
}
int mid = (l + r) >> 1, j = l;
cdq(l, mid);
cdq(mid + 1, r);
sort(a + l, a + mid + 1, _comp);
sort(a + mid + 1, a + r + 1, _comp);
for (int i = mid + 1; i <= r; i++) {
while (j <= mid && a[j].b <= a[i].b) {
ta.update(a[j].c, a[j].ctr);
j++;
}
a[i].ans += ta.query(a[i].c);
}
for (int i = l; i < j; i++) { ta.update(a[i].c, -a[i].ctr); }
}
int main() {
scanf("%d %d", &n, &k);
ta.mn = k;
for (int i = 1; i <= n; i++) {
scanf("%d %d %d", &v[i].a, &v[i].b, &v[i].c);
}
sort(v + 1, v + n + 1, comp);
for (int i = 1; i <= n; i++) {
if (i != 1 && v[i] == v[i – 1]) {
a[t].ctr++;
} else {
a[++t] = v[i];
a[t].ctr = 1;
}
}
cdq(1, t);
for (int i = 1; i <= t; i++) {
b[a[i].ans] += a[i].ctr;
}
for (int i = 0; i < n; i++) {
printf("%d\n", b[i]);
}
return 0;
}
“`