hihocoder1699

链接: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\n", ret[i]);
101     return 0;
102 }
View Code

 

posted @ 2018-02-25 22:40  shuguangzw  阅读(282)  评论(0编辑  收藏  举报