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 }