-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcdq.cpp
More file actions
95 lines (94 loc) · 1.98 KB
/
cdq.cpp
File metadata and controls
95 lines (94 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// CDQ divide and conquer
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1000005;
const int mod = 998244353;
int k;
struct s
{
int x, y, z;
int cnt, ans, id;
};
vector<s>v;
int b[MAXN];
void update(int x, int d) {
while (x <= 100000) {
b[x] += d;
x += x & (-x);
}
}
int query(int x) {
int ret = 0;
while (x) {
ret += b[x];
x -= x & (-x);
}
return ret;
}
bool cmp(s x, s y) {
if (x.x != y.x) {
return x.x < y.x;
}
if (x.y != y.y) {
return x.y < y.y;
}
return x.z < y.z;
}
bool cmp2(s x, s y) {
if (x.y != y.y) {
return x.y < y.y;
}
return x.z < y.z;
}
void cdq(int l, int r) {
if (l == r) {
v[l].ans += v[l].cnt - 1;
return;
}
int mid = (l + r) >> 1;
cdq(l, mid);
cdq(mid + 1, r);
sort(v.begin()+l, v.begin() + mid + 1, cmp2);
sort(v.begin() + mid + 1, v.begin() + r + 1, cmp2);
int ptr = l;
for (int i = mid + 1 ; i <= r; i++) {
while (ptr <= mid && v[ptr].y <= v[i].y) {
update(v[ptr].z,v[ptr].cnt);
ptr++;
}
v[i].ans += query(v[i].z);
}
for (int i = l ; i < ptr; i++) {
update(v[i].z, -v[i].cnt);
}
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--) {
v.clear();
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int x, y, z;
cin >> x >> y >> z;
v.push_back({x,y,z,1,0,i});
}
sort((v).begin(), (v).end(), cmp);
cdq(0, v.size() - 1);
vector<int>ans(n,0);
for (auto i= n - 1 ; i >= 0 ; i--) {
if (i + 1 < n && v[i].x == v[i+1].x && v[i].y == v[i+1].y && v[i].z == v[i+1].z) {
ans[v[i].id] = ans[v[i+1].id];
}
else {
ans[v[i].id] = v[i].ans;
}
}
for (auto i:ans) {
cout << i << '\n';
}
}
}