73 lines
1.7 KiB
C++
73 lines
1.7 KiB
C++
#include <algorithm>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
using namespace std;
|
|
typedef long long LL;
|
|
const int kMaxn = 1e5 + 10;
|
|
int n, m, c[kMaxn * 2], res[kMaxn], cnt;
|
|
inline void Modify(int p, int v) {
|
|
for (; p <= m; p += p & (-p)) c[p] += v;
|
|
}
|
|
inline int Query(int p) {
|
|
int res = 0;
|
|
for (; p > 0; p -= p & (-p)) res += c[p];
|
|
return res;
|
|
}
|
|
struct Data {
|
|
int a, b, c, w, f;
|
|
};
|
|
Data val[kMaxn], tmp[kMaxn];
|
|
bool cmp(const Data &x, const Data &y) {
|
|
if (x.a != y.a) return x.a < y.a;
|
|
if (x.b != y.b) return x.b < y.b;
|
|
return x.c < y.c;
|
|
}
|
|
void CDQ(int L, int R) {
|
|
if (L == R) return;
|
|
int M = (L + R) >> 1;
|
|
CDQ(L, M);
|
|
CDQ(M + 1, R);
|
|
int p = L, q = M + 1, d = L;
|
|
while (p <= M && q <= R) {
|
|
if (val[p].b <= val[q].b) {
|
|
Modify(val[p].c, val[p].w);
|
|
tmp[d++] = val[p++];
|
|
} else {
|
|
val[q].f += Query(val[q].c);
|
|
tmp[d++] = val[q++];
|
|
}
|
|
}
|
|
while (p <= M) {
|
|
Modify(val[p].c, val[p].w);
|
|
tmp[d++] = val[p++];
|
|
}
|
|
while (q <= R) {
|
|
val[q].f += Query(val[q].c);
|
|
tmp[d++] = val[q++];
|
|
}
|
|
for (int i = L; i <= M; i++) Modify(val[i].c, -val[i].w);
|
|
for (int i = L; i <= R; i++) val[i] = tmp[i];
|
|
}
|
|
int main() {
|
|
#ifdef local
|
|
freopen("pro.in", "r", stdin);
|
|
#endif
|
|
scanf("%d%d", &n, &m);
|
|
for (int i = 1; i <= n; i++) {
|
|
scanf("%d%d%d", &val[i].a, &val[i].b, &val[i].c);
|
|
val[i].w = 1;
|
|
}
|
|
sort(val + 1, val + 1 + n, cmp);
|
|
cnt = 1;
|
|
for (int i = 2; i <= n; i++) {
|
|
if (val[i].a == val[cnt].a && val[i].b == val[cnt].b &&
|
|
val[i].c == val[cnt].c)
|
|
val[cnt].w++;
|
|
else
|
|
val[++cnt] = val[i];
|
|
}
|
|
CDQ(1, cnt);
|
|
for (int i = 1; i <= cnt; i++) res[val[i].f + val[i].w - 1] += val[i].w;
|
|
for (int i = 0; i < n; i++) printf("%d\n", res[i]);
|
|
return 0;
|
|
} |