new file: P3810.cpp
This commit is contained in:
1 parent
8838760724
commit
d0bcccde01
1 file changed
+91
@@ -0,0 +1,91 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int maxn = 100005;
|
||||
struct Node {
|
||||
int a, b, c;
|
||||
int cnt = 1; // 相同三元组的个数
|
||||
int id = 0; // 在去重数组中的编号
|
||||
bool operator<(const Node &o) const {
|
||||
if (a != o.a)
|
||||
return a < o.a;
|
||||
if (b != o.b)
|
||||
return b < o.b;
|
||||
return c < o.c;
|
||||
}
|
||||
} e[maxn], tmp[maxn];
|
||||
int n, k, m;
|
||||
int ans[maxn]; // ans[i]: 去重后第 i 个元素的答案
|
||||
int res[maxn]; // res[d]: 答案恰为 d 的元素个数
|
||||
struct BIT {
|
||||
int tree[200005];
|
||||
int lowbit(int x) { return x & -x; }
|
||||
void add(int x, int v) {
|
||||
for (; x <= k; x += lowbit(x))
|
||||
tree[x] += v;
|
||||
}
|
||||
int sum(int x) {
|
||||
int r = 0;
|
||||
for (; x > 0; x -= lowbit(x))
|
||||
r += tree[x];
|
||||
return r;
|
||||
}
|
||||
} bit;
|
||||
void cdq(int l, int r) {
|
||||
if (l == r)
|
||||
return;
|
||||
int mid = (l + r) >> 1;
|
||||
cdq(l, mid);
|
||||
cdq(mid + 1, r);
|
||||
// 左半 -> 右半 的贡献:b 用双指针,c 用树状数组
|
||||
int i = l, j = mid + 1;
|
||||
while (j <= r) {
|
||||
while (i <= mid && e[i].b <= e[j].b) {
|
||||
bit.add(e[i].c, e[i].cnt);
|
||||
++i;
|
||||
}
|
||||
ans[e[j].id] += bit.sum(e[j].c);
|
||||
++j;
|
||||
}
|
||||
// 撤销树状数组(不能 memset,太慢,要按插入的反操作回滚)
|
||||
for (int t = l; t < i; ++t)
|
||||
bit.add(e[t].c, -e[t].cnt);
|
||||
// 归并:让 e[l..r] 按 b 有序,供上一层双指针使用
|
||||
i = l;
|
||||
j = mid + 1;
|
||||
int t = l;
|
||||
while (i <= mid && j <= r)
|
||||
tmp[t++] = (e[i].b <= e[j].b) ? e[i++] : e[j++];
|
||||
while (i <= mid)
|
||||
tmp[t++] = e[i++];
|
||||
while (j <= r)
|
||||
tmp[t++] = e[j++];
|
||||
for (t = l; t <= r; ++t)
|
||||
e[t] = tmp[t];
|
||||
}
|
||||
|
||||
int main() {
|
||||
scanf("%d%d", &n, &k);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
scanf("%d%d%d", &e[i].a, &e[i].b, &e[i].c);
|
||||
sort(e + 1, e + n + 1);
|
||||
// 去重
|
||||
m = 0;
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (i > 1 && e[i].a == e[m].a && e[i].b == e[m].b && e[i].c == e[m].c) {
|
||||
++e[m].cnt;
|
||||
} else {
|
||||
e[++m] = e[i];
|
||||
e[m].cnt = 1;
|
||||
}
|
||||
}
|
||||
for (int i = 1; i <= m; ++i)
|
||||
e[i].id = i;
|
||||
cdq(1, m);
|
||||
for (int i = 1; i <= m; ++i) {
|
||||
ans[e[i].id] += e[i].cnt - 1; // 与自己完全相同的同族元素
|
||||
res[ans[e[i].id]] += e[i].cnt;
|
||||
}
|
||||
for (int d = 0; d < n; ++d)
|
||||
printf("%d\n", res[d]);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user