链接:http://hihocoder.com/problemset/problem/1699
快毕业了的菜菜,做了个比赛,遇到四维偏序,调成了傻逼,所以记录下,看了下以前的傻逼代码,发现自己的cdq居然用sort
怪不得总是被卡常,然后就是套路cdq+cdq,这类题的坑点就是有相同的矩形
贴代码:
1 #include <stdio.h> 2 #include <algorithm> 3 using namespace std; 4 typedef long long LL; 5 const LL N = 1e5 + 5; 6 const LL mod = 1e9 + 9; 7 8 struct Point { 9 int x1, y1, x2, y2, partition, id; 10 bool operator < (const Point &p) const { 11 if(x1 != p.x1) return x1 < p.x1; 12 if(y1 != p.y1) return y1 < p.y1; 13 if(x2 != p.x2) return x2 > p.x2; 14 if(y2 != p.y2) return y2 > p.y2; 15 return id < p.id; 16 } 17 }p[N], o[N], tmp[N]; 18 19 int n, bit[N], lim, ret[N]; 20 21 void add(int x, int ad) { 22 for(; x <= lim; x += x & -x) bit[x] += ad; 23 } 24 25 int ask(int x) { 26 int sum = 0; 27 for(; x > 0; x -= x & -x) sum += bit[x]; 28 return sum; 29 } 30 31 void cdq(int l, int r) { 32 if(l == r) return; 33 int mid = l + r >> 1; 34 cdq(l, mid); cdq(mid + 1, r); 35 int i = l, j = mid + 1, cnt = l; 36 while(i <= mid || j <= r) { 37 if(i > mid) { 38 if(o[j].partition) ret[o[j].id] += ask(lim) - ask(o[j].y2 - 1); 39 tmp[cnt ++] = o[j ++]; 40 } else if(j > r) { 41 if(!o[i].partition) add(o[i].y2, 1); 42 tmp[cnt ++] = o[i ++]; 43 } else if(o[i].x2 >= o[j].x2) { 44 if(!o[i].partition) add(o[i].y2, 1); 45 tmp[cnt ++] = o[i ++]; 46 } else { 47 if(o[j].partition) ret[o[j].id] += ask(lim) - ask(o[j].y2 - 1); 48 tmp[cnt ++] = o[j ++]; 49 } 50 } 51 for(i = l; i <= mid; ++ i) if(!o[i].partition) add(o[i].y2, -1); 52 for(i = l; i <= r; ++ i) o[i] = tmp[i]; 53 } 54 55 56 bool cmp(const Point &a, const Point &b) { 57 if(a.y1 != b.y1) return a.y1 < b.y1; 58 if(a.x2 != b.x2) return a.x2 > b.x2; 59 if(a.y2 != b.y2) return a.y2 > b.y2; 60 return a.id < b.id; 61 } 62 63 void solve(int l, int r) { 64 if(l == r) return; 65 int mid = l + r >> 1; 66 solve(l, mid); solve(mid + 1, r); 67 int i = l, j = mid + 1, cnt = l - 1; 68 while(i <= mid || j <= r) { 69 if(i > mid) o[++ cnt] = p[j ++], o[cnt].partition = 1; 70 else if(j > r) o[++ cnt] = p[i ++], o[cnt].partition = 0; 71 else if(cmp(p[i], p[j])) o[++ cnt] = p[i ++], o[cnt].partition = 0; 72 else o[++ cnt] = p[j ++], o[cnt].partition = 1; 73 } 74 for(i = l; i <= r; ++ i) { 75 p[i] = o[i]; 76 } 77 cdq(l, r); 78 } 79 int main() { 80 scanf("%d", &n); 81 for(int i = 1; i <= n; ++ i) { 82 scanf("%d%d%d%d", &p[i].x1, &p[i].y1, &p[i].x2, &p[i].y2); 83 bit[++ lim] = p[i].y2; 84 p[i].id = i; 85 } 86 sort(bit + 1, bit + 1 + lim); 87 lim = unique(bit + 1, bit + 1 + lim) - bit - 1; 88 for(int i = 1; i <= n; ++ i) { 89 p[i].y2 = lower_bound(bit + 1, bit + 1 + lim, p[i].y2) - bit; 90 } 91 for(int i = 1; i <= lim; ++ i) bit[i] = 0; 92 sort(p + 1, p + 1 + n); 93 solve(1, n); 94 sort(p + 1, p + 1 + n); 95 for(int i = n - 1; i > 0; -- i) { 96 if(p[i].x1 == p[i + 1].x1 && p[i].y1 == p[i + 1].y1) 97 if(p[i].x2 == p[i + 1].x2 && p[i].y2 == p[i + 1].y2) 98 ret[p[i].id] = ret[p[i+1].id]; 99 } 100 for(int i = 1; i <= n; ++ i) printf("%d ", ret[i]); 101 return 0; 102 }