zoukankan      html  css  js  c++  java
  • 【Foreign】Rectangle [KD-tree]

    Rectangle

    Time Limit: 50 Sec  Memory Limit: 512 MB

    Description

      

    Input

      

    Output

      

    Sample Input

      0
      4
      2 0
      2 1
      1 1
      1 2
      4
      0 0 2 2
      1 1 2 2
      1 0 2 1
      0 0 1 1

    Sample Output

      2 3
      2 2
      2 2
      1 1

    HINT

      

    Solution

      显然,如果我们求出了 last[i] 表示 在某个相同横/纵坐标下,前一个纵/横坐标的取值,那问题就转化为了三维偏序,且要求在线

      限制显然形如:L1 <= xi <= R1, L2 <= yi <= R2, last_i <= L3

      由于BearChild太菜了,它的 bitset 内存不够开。直接上个 KD-tree 卡卡常即可。

    Code

      1 #include<iostream>
      2 #include<string>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cmath>
      8 using namespace std;
      9 typedef long long s64;
     10 
     11 const int ONE = 500005;
     12 const int Max = 500000;
     13 
     14 int get()
     15 {
     16         int res = 1, Q = 1; char c;
     17         while( (c = getchar()) < 48 || c > 57)
     18             if(c == '-') Q = -1;
     19         if(Q) res = c - 48;
     20         while( (c = getchar()) >= 48 && c <= 57)
     21             res = res * 10 + c - 48;
     22         return res * Q;
     23 }
     24 int T, n;
     25 
     26 struct node {int x, y;} fir[ONE];
     27 bool cmp_x(const node &a, const node &b) {return a.x < b.x || (a.x == b.x && a.y < b.y);}
     28 bool cmp_y(const node &a, const node &b) {return a.y < b.y || (a.y == b.y && a.x < b.x);}
     29 
     30 struct power {int c[3];};
     31 bool cmp_0(const power &a, const power &b) {return a.c[0] < b.c[0];}
     32 bool cmp_1(const power &a, const power &b) {return a.c[1] < b.c[1];}
     33 bool cmp_2(const power &a, const power &b) {return a.c[2] < b.c[2];}
     34 
     35 int Ans;
     36 struct ID
     37 {
     38         struct point {int lc, rc, size, l[3], r[3];} p[ONE];
     39         power a[ONE];
     40 
     41         int kd_num;
     42         void Update(point &x)
     43         {
     44             if(x.lc) x.size += p[x.lc].size;
     45             if(x.rc) x.size += p[x.rc].size;
     46             point y;
     47             if(x.lc) y = p[x.lc],
     48                 x.l[0] = min(x.l[0], y.l[0]), x.r[0] = max(x.r[0], y.r[0]),
     49                 x.l[1] = min(x.l[1], y.l[1]), x.r[1] = max(x.r[1], y.r[1]),
     50                 x.l[2] = min(x.l[2], y.l[2]), x.r[2] = max(x.r[2], y.r[2]);
     51             if(x.rc) y = p[x.rc],
     52                 x.l[0] = min(x.l[0], y.l[0]), x.r[0] = max(x.r[0], y.r[0]),
     53                 x.l[1] = min(x.l[1], y.l[1]), x.r[1] = max(x.r[1], y.r[1]),
     54                 x.l[2] = min(x.l[2], y.l[2]), x.r[2] = max(x.r[2], y.r[2]);
     55         }
     56 
     57         s64 calc(int l, int r, int id)
     58         {
     59             s64 x = 0, xx = 0;
     60             for(int i = l; i <= r; i++)
     61                 x += a[i].c[id], xx += (s64)a[i].c[id] * a[i].c[id];
     62             return (r - l + 1) * xx - x * x;
     63         }
     64 
     65         int root;
     66         int Build(int l, int r)
     67         {
     68             int mid = l + r >> 1;
     69             point &x = p[mid];
     70 
     71             s64 w0 = calc(l, r, 0), w1 = calc(l, r, 1), w2 = calc(l, r, 2);
     72             s64 w = max(w0, max(w1, w2));
     73 
     74             if(w == w0) nth_element(a + l, a + mid, a + r + 1, cmp_0);
     75             else
     76             if(w == w1) nth_element(a + l, a + mid, a + r + 1, cmp_1);
     77             else
     78             if(w == w2) nth_element(a + l, a + mid, a + r + 1, cmp_2);
     79 
     80             if(l < mid) x.lc = Build(l, mid - 1);
     81             if(mid < r) x.rc = Build(mid + 1, r);
     82 
     83             x.size = 1;
     84             x.l[0] = x.r[0] = a[mid].c[0];
     85             x.l[1] = x.r[1] = a[mid].c[1];
     86             x.l[2] = x.r[2] = a[mid].c[2];
     87             Update(x);
     88             return mid;
     89         }
     90 
     91         bool insect(const point &a, const point &b)
     92         {
     93             if(a.r[0] < b.l[0] || b.r[0] < a.l[0]) return 0;
     94             if(a.r[1] < b.l[1] || b.r[1] < a.l[1]) return 0;
     95             if(a.r[2] < b.l[2] || b.r[2] < a.l[2]) return 0;
     96             return 1;
     97         }
     98 
     99         bool contain(const point &a, const point &b) 
    100         {
    101             if(!(a.l[0] <= b.l[0] && b.r[0] <= a.r[0])) return 0;
    102             if(!(a.l[1] <= b.l[1] && b.r[1] <= a.r[1])) return 0;
    103             if(!(a.l[2] <= b.l[2] && b.r[2] <= a.r[2])) return 0;
    104             return 1;
    105         }
    106 
    107         bool contain(const point &a, const power &b)
    108         {
    109             if(!(a.l[0] <= b.c[0] && b.c[0] <= a.r[0])) return 0;
    110             if(!(a.l[1] <= b.c[1] && b.c[1] <= a.r[1])) return 0;
    111             if(!(a.l[2] <= b.c[2] && b.c[2] <= a.r[2])) return 0;
    112             return 1;
    113         }
    114 
    115         void Query(int i, const point &x)
    116         {
    117             point now = p[i];
    118             if(!insect(x, now)) return;
    119             if(contain(x, now)) {Ans += now.size; return;}
    120             if(contain(x, a[i])) Ans++;
    121             if(now.lc) Query(now.lc, x);
    122             if(now.rc) Query(now.rc, x);
    123         }
    124 };
    125 ID A, B;
    126 
    127 
    128 void Make_1()//|
    129 {
    130         sort(fir + 1, fir + n + 1, cmp_y);
    131         static int last[ONE];
    132         for(int i = 0; i <= Max; i++) last[i] = -1;
    133         for(int i = 1; i <= n; i++)
    134         {
    135             A.a[i].c[0] = fir[i].x;
    136             A.a[i].c[1] = fir[i].y;
    137             A.a[i].c[2] = last[fir[i].x];
    138             last[fir[i].x] = fir[i].y;
    139         }
    140         A.root = A.Build(1, n);
    141 }
    142 
    143 void Make_2()
    144 {
    145         sort(fir + 1, fir + n + 1, cmp_x);
    146         static int last[ONE];
    147         for(int i = 0; i <= Max; i++) last[i] = -1;
    148         for(int i = 1; i <= n; i++)
    149         {
    150             B.a[i].c[0] = fir[i].x;
    151             B.a[i].c[1] = fir[i].y;
    152             B.a[i].c[2] = last[fir[i].y];
    153             last[fir[i].y] = fir[i].x;
    154         }
    155         B.root = B.Build(1, n);
    156 }
    157 
    158 int main()
    159 {
    160         T = get(), n = get();
    161         for(int i = 1; i <= n; i++)
    162             fir[i].x = get(), fir[i].y = get();
    163         Make_1(), Make_2();
    164         int Q = get(), lax = 0, lay = 0;
    165         while(Q--)
    166         {
    167             int x_1 = get(), y_1 = get(), x_2 = get(), y_2 = get();
    168             x_1 = x_1 + (lax + lay) * T, y_1 = y_1 + (lax + lay) * T;
    169             x_2 = x_2 + (lax + lay) * T, y_2 = y_2 + (lax + lay) * T;
    170             ID::point x;
    171 
    172             Ans = x.size = x.lc = x.rc = 0;
    173             x.l[0] = x_1, x.r[0] = x_2, x.l[1] = y_1, x.r[1] = y_2;
    174             x.l[2] = -1, x.r[2] = y_1 - 1;
    175             A.Query(A.root, x), lax = Ans;
    176             
    177             Ans = x.size = x.lc = x.rc = 0;
    178             x.l[0] = x_1, x.r[0] = x_2, x.l[1] = y_1, x.r[1] = y_2;
    179             x.l[2] = -1, x.r[2] = x_1 - 1;
    180             B.Query(B.root, x), lay = Ans;
    181 
    182             printf("%d %d
    ", lax, lay);
    183         }
    184 }
    View Code
  • 相关阅读:
    Java面向对象---重写(Override)与重载(Overload)
    Java面向对象---继承
    Java 异常处理
    Java 正则表达式
    Java 日期时间
    Java Number & Math 类
    Java StringBuffer 和 StringBuilder 类
    使用老毛桃安装Windows操作系统
    Horizon代码的层次结构
    云平台-资源监控模块和分布式日志采集系统模块
  • 原文地址:https://www.cnblogs.com/BearChild/p/8206562.html
Copyright © 2011-2022 走看看