TLE 50pts, 盲猜是因为线段树常数大
#include <bits/stdc++.h>
using std::cin;
using std::cout;
const int MAX = 1e5 + 5;
int n, mx, m;
int rt[(MAX << 4) + 5], ans[(MAX << 1) + 5];
struct N
{
int a, b, c, cnt, ans;
bool operator != (N x)
{
return (a != x.a or b != x.b or c != x.c);
}
} a[MAX], b[MAX];
bool cmpB(N n1, N n2)
{
if (n1.b == n2.b) { return n1.c < n2.c; }
return n1.b < n2.b;
}
bool cmpA(N n1, N n2)
{
if (n1.a == n2.a) { return cmpB(n1, n2); }
return n1.a < n2.a;
}
void add(int l, int r, int s, int v, int x)
{
if (l == r and l == s) { rt[x] += v; return ; }
int k = l + ((r - l) >> 1);
if (s <= k) { add(l, k, s, v, x << 1); }
else { add(k + 1, r, s, v, x << 1 | 1); }
rt[x] = rt[x << 1] + rt[x << 1 | 1];
}
int get(int l, int r, int s, int t, int x)
{
if (l >= s and r <= t) { return rt[x]; }
int k = l + ((r - l) >> 1), tmp = 0;
if (k >= s) { tmp += get(l, k, s, t, x << 1); }
if (k < t) { tmp += get(k + 1, r, s, t, x << 1 | 1); }
return tmp;
}
void clear(int l, int r, int x)
{
rt[x] = 0;
if (l == r) { return ; }
int k = l + ((r - l) >> 1);
clear(l, k, x << 1);
clear(k + 1, r, x << 1 | 1);
}
void cdq(int l, int r)
{
if (l == r) { return ; }
int k = l + ((r - l) >> 1);
cdq(l, k); cdq(k + 1, r);
std::sort(b + l, b + k + 1, cmpB);
std::sort(b + k + 1, b + r + 1, cmpB);
int i = l, j = k + 1;
while (j <= r)
{
while (i <= k)
{
if (b[i].b <= b[j].b) { add(1, mx, b[i].c, b[i].cnt, 1); }
else { break; }
++i;
}
b[j].ans += get(1, mx, 1, b[j].c, 1);
++j;
}
clear(1, mx, 1);
}
int main()
{
cin.tie(NULL);
cout.tie(NULL);
std::ios::sync_with_stdio(false);
cin >> n >> mx;
for (int i = 1; i <= n; ++i) { cin >> a[i].a >> a[i].b >> a[i].c; }
std::sort(a + 1, a + n + 1, cmpA);
int tmp = 0;
for (int i = 1; i <= n; ++i)
{
++tmp;
if (a[i] != a[i + 1])
{
++m;
b[m] = {a[i].a, a[i].b, a[i].c, tmp, 0};
tmp = 0;
}
}
cdq(1, m);
for (int i = 1; i <= m; ++i) { ans[b[i].ans + b[i].cnt - 1] += b[i].cnt; }
for (int i = 0; i < n; ++i) { cout << ans[i] << '\n'; }
return 0;
}