首页 > 代码库 > HDU 5618:Jam's problem again(CDQ分治+树状数组处理三维偏序)

HDU 5618:Jam's problem again(CDQ分治+树状数组处理三维偏序)

http://acm.hdu.edu.cn/showproblem.php?pid=5618

题意:……

思路:和NEUOJ那题一样的。重新写了遍理解了一下,算作处理三维偏序的模板了。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 using namespace std;
 6 #define INF 0x3f3f3f3f
 7 #define N 100010
 8 typedef long long LL;
 9 struct node {
10     int x, y, z, id, f;
11 } p[N], s[N];
12 int ans[N], same[N], bit[N], gap;
13 
14 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; }
15 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; }
16 bool cmpid(const node &a, const node &b) { return a.id < b.id; }
17 bool check(node a, node b) { return a.x == b.x && a.y == b.y && a.z == b.z; }
18 
19 int lowbit(int x) { return x & (-x); }
20 
21 void update(int x, int w) { while(x <= gap) bit[x] += w, x += lowbit(x); }
22 
23 int query(int x) { int ans = 0; while(x) ans += bit[x], x -= lowbit(x); return ans; }
24 
25 void CDQ(int l, int r) {
26     if(l == r) return ;
27     int m = (l + r) >> 1;
28     CDQ(l, m); CDQ(m + 1, r);
29     int cnt = 0;
30     // 标记是在左边还是右边
31     for(int i = l; i <= r; i++) s[++cnt] = p[i], s[cnt].f = i <= m ? 0 : 1;
32     sort(s + 1, s + 1 + cnt, cmpy);
33     for(int i = 1; i <= cnt; i++)
34         if(!s[i].f) update(s[i].z, 1);
35         else ans[s[i].id] += query(s[i].z);
36     for(int i = 1; i <= cnt; i++)
37         if(!s[i].f) update(s[i].z, -1);
38 }
39 
40 int main() {
41     int t, n;
42     scanf("%d", &t);
43     while(t--) {
44         scanf("%d", &n); gap = 0;
45         for(int i = 1; i <= n; i++) {
46             scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z);
47             p[i].id = i; if(p[i].z > gap) gap = p[i].z;
48         }
49         sort(p + 1, p + 1 + n, cmpx);
50         // 离散化
51         for(int i = 1; i <= n; ) {
52             int j = i + 1;
53             while(j <= n && check(p[j], p[i])) j++;
54             while(i < j) same[p[i++].id] = p[j-1].id;
55         }
56         for(int i = 1; i <= n; i++) p[i].x = i;
57         memset(bit, 0, sizeof(bit));
58         memset(ans, 0, sizeof(ans));
59         CDQ(1, n);
60         sort(p + 1, p + 1 + n, cmpid);
61         for(int i = 1; i <= n; i++) printf("%d\n", ans[same[i]]);
62     }
63     return 0;
64 }

 

HDU 5618:Jam's problem again(CDQ分治+树状数组处理三维偏序)