#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL #include "algo/debug.h" #else #define debug(...) 42 #endif
#define rep(i, a, n) for (int i = a; i <= n; i++) #define per(i, a, n) for (int i = n; i >= a; i--) #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) #define mp make_pair #define pb push_back #define fi first #define se second #define pi acos(-1) #define il inline #define rg register #define SZ(x) ((int)(x).size()) #define all(x) x.begin(), x.end() #define INF 0x7fffffff #define inf 0x3f3f3f3f #define MOD 998244353 #define mod 1000000007 typedef vector<int> VI; typedef pair<int, int> PII; typedef long long ll; typedef double db; ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
namespace FAST_IO { #define ll long long #define ull unsigned long long #define db double #define _8 __int128_t const int LEN = 1 << 20; char BUF[LEN], PUF[LEN]; int Pin = LEN, Pout; inline void flushin() { memcpy(BUF, BUF + Pin, LEN - Pin), fread(BUF + LEN - Pin, 1, Pin, stdin), Pin = 0; return; } inline void flushout() { fwrite(PUF, 1, Pout, stdout), Pout = 0; return; } inline char Getc() { return (Pin == LEN ? (fread(BUF, 1, LEN, stdin), Pin = 0) : 0), BUF[Pin++]; } inline char Get() { return BUF[Pin++]; } inline void Putc(char x) { if (Pout == LEN) flushout(), Pout = 0; PUF[Pout++] = x; } inline void Put(char x) { PUF[Pout++] = x; } template <typename tp = int> inline tp read() { (Pin + 32 >= LEN) ? flushin() : void(); tp res = 0; char f = 1, ch = ' '; for (; ch < '0' || ch > '9'; ch = Get()) if (ch == '-') f = -1; for (; ch >= '0' && ch <= '9'; ch = Get()) res = (res << 3) + (res << 1) + ch - 48; return res * f; } template <typename tp> inline void wt(tp a) { if (a > 9) wt(a / 10); Put(a % 10 + '0'); return; } template <typename tp> inline void write(tp a, char b = '\n') { static int stk[20], top; (Pout + 32 >= LEN) ? flushout() : void(); if (a < 0) Put('-'), a = -a; else if (a == 0) Put('0'); for (top = 0; a; a /= 10) stk[++top] = a % 10; for (; top; --top) Put(stk[top] ^ 48); Put(b); return; } inline void wt_str(std::string s) { for (char i : s) Putc(i); return; } } using namespace FAST_IO;
struct Element { int a, b, c; int id; };
int main() { int n, k; n = read(), k = read();
vector<Element> e(n + 1);
rep(i, 1, n) e[i].a = read(), e[i].b = read(), e[i].c = read(), e[i].id = i;
sort(e.begin() + 1, e.begin() + 1 + n, [&](const Element &x, const Element &y) { return (x.a == y.a) ? ((x.b == y.b) ? (x.c < y.c) : (x.b < y.b)) : (x.a < y.a); });
VI ID(n + 1), num(n + 1, 0);
for (int i = 1; i <= n;) { int j = i + 1; while (j <= n && e[i].a == e[j].a && e[i].b == e[j].b && e[i].c == e[j].c) ++j; while (i < j) ID[e[i].id] = e[j - 1].id, ++i; }
rep(i, 1, n) e[i].a = i;
VI c(k + 1, 0);
auto mark = [&](int x, int v) { for (; x <= k; x += x & -x) c[x] += v; };
auto query = [&](int x) { int res = 0; for (; x; x -= x & -x) res += c[x]; return res; };
function<void(int, int)> cdq = [&](int l, int r) { if (l == r) return; int mid = (l + r) / 2; cdq(l, mid); cdq(mid + 1, r); sort(e.begin() + l, e.begin() + r + 1, [&](const Element &x, const Element &y) { return (x.b == y.b) ? ((x.c == y.c) ? (x.a < y.a) : (x.c < y.c)) : (x.b < y.b); }); rep(i, l, r) { if (e[i].a <= mid) mark(e[i].c, 1); else num[e[i].id] += query(e[i].c); }
rep (i, l, r) if (e[i].a <= mid) mark(e[i].c, -1); };
cdq(1, n);
VI f(n + 1, 0); rep (i, 1, n) f[num[ID[e[i].id]]]++; for (int i = 0; i < n; ++i) write(f[i], '\n');
flushout(); return 0; }
|