http://acm.neu.edu.cn/hustoj/problem.php?id=1702
思路:三维偏序模板题,用CDQ分治+树状数组或者树套树。对于三元组(x,y,z),先对x进行排序,然后对x进行CDQ分治降维,在分治的区间对y进行排序,用树状数组维护z。
还不太理解CDQ分治。等待UPDATE。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long LL;
#define N 100010
#define INF 0x3f3f3f3f
struct node {
int id, x, y, z;
node () {}
node (int x, int y, int z, int id) : x(x), y(y), z(z), id(id) {}
bool operator == (const node &A) const {
return (x == A.x && y == A.y && z == A.z);
}
} p[N]; int gap, same[N], bit[N], ans[N]; bool cmpx(const node &a, const node &b) {
if(a.x != b.x) return a.x < b.x;
if(a.y != b.y) return a.y < b.y;
return a.z < b.z;
} bool cmpy(const node &a, const node &b) {
if(a.y != b.y) return a.y < b.y;
if(a.x != b.x) return a.x < b.x;
return a.z < b.z;
} bool cmpid(const node &a, const node &b) { return a.id < b.id; } int lowbit(int x) { return x & (-x); } void update(int x, int val) {
while(x <= gap) {
bit[x] += val;
x += lowbit(x);
}
} int query(int x) {
int ans = ;
while(x) {
ans += bit[x];
x -= lowbit(x);
}
return ans;
} void CDQ(int l, int r) {
if(l == r) return ;
int mid = (l + r) >> ;
CDQ(l, mid); CDQ(mid + , r);
sort(p + l, p + r + , cmpy);
for(int i = l; i <= r; i++)
if(p[i].x <= mid) update(p[i].z, );
else ans[p[i].id] += query(p[i].z);
for(int i = l; i <= r; i++)
if(p[i].x <= mid) update(p[i].z, -);
} int main()
{
int t;
scanf("%d", &t);
while(t--) {
int n, a, b, c;
scanf("%d", &n);
gap = ;
for(int i = ; i <= n; i++) {
scanf("%d%d%d", &a, &b, &c);
p[i] = node(a, b, c, i);
if(c > gap) gap = c;
}
sort(p + , p + + n, cmpx);
memset(same, , sizeof(same));
for(int i = ; i <= n; ) {
int j = i + ;
while(p[i] == p[j] && j <= n) j++;
while(i < j) same[p[i++].id] = p[j-].id;
}
memset(bit, , sizeof(bit));
memset(ans, , sizeof(ans));
for(int i = ; i <= n; i++) p[i].x = i;
CDQ(, n);
sort(p + , p + + n, cmpid);
for(int i = ; i <= n; i++)
printf("%d\n", ans[same[p[i].id]]);
}
return ;
}