P2093 [国家集训队]JZPFAR

 

P2093 [国家集训队]JZPFAR

https://www.luogu.org/problemnew/show/P2093

 

分析:

  kdtree模板

  维护一个小根堆,开始时插入k个-inf,每次取出最小的与当前更新,如果当前的更大一些,那么更新堆中的元素。

 

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long LL;
  4 
  5 inline int read() {
  6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
  7     for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
  8 }
  9 
 10 const int N = 200010;
 11 const int DIM = 2;
 12 const LL INF = 1e9;
 13  
 14 struct Point{
 15     LL x[2];int id;
 16     Point() {x[0] = 0;x[1] = 0;}
 17     Point(LL a,LL b) {x[0] = a,x[1] = b;}
 18     LL& operator[](int c){return x[c];}
 19 }P[N],Q;
 20 struct KDtree{
 21     int ch[2],mn[2],mx[2];
 22     Point p;
 23 }T[N<<1];
 24 struct State{
 25     LL dis;int id;
 26     State() {}
 27     State(LL a,LL b) {dis = a,id = b;}
 28     bool operator < (const State &A) const {
 29         if (dis == A.dis) return id < A.id;
 30         return dis > A.dis;
 31     }
 32 };
 33 priority_queue <State> q;
 34 int Cur,CntNode,Root;
 35 
 36 #define lc T[rt].ch[0]
 37 #define rc T[rt].ch[1]
 38 
 39 bool cmp(Point a,Point b) {
 40     return a.x[Cur] < b.x[Cur];
 41 }
 42 void pushup(int rt) {
 43     for (int i=0; i<DIM; ++i) {
 44         if (lc) T[rt].mn[i] = min(T[rt].mn[i], T[lc].mn[i]), T[rt].mx[i] = max(T[rt].mx[i],T[lc].mx[i]);
 45         if (rc) T[rt].mn[i] = min(T[rt].mn[i], T[rc].mn[i]), T[rt].mx[i] = max(T[rt].mx[i],T[rc].mx[i]);
 46     }
 47 }
 48 void NewNode(int rt,Point p) {
 49     T[rt].p = p;
 50     T[rt].mn[0] = T[rt].mx[0] = p.x[0];
 51     T[rt].mn[1] = T[rt].mx[1] = p.x[1];
 52 }
 53 int build(int l,int r,int cd) {
 54     if (l > r) return 0;
 55     int m = (l + r) >> 1,rt = m;
 56     Cur = cd; nth_element(P+l, P+m, P+r+1, cmp);
 57     NewNode(rt,P[m]);
 58     lc = build(l, m-1, cd^1); 
 59     rc = build(m+1, r, cd^1);
 60     pushup(rt);
 61     return rt;
 62 }
 63 /*void Insert(Point p,int &rt,int cd) {
 64     if (!rt) {
 65         NewNode(rt = ++CntNode, p); return ;
 66     }
 67     if (p.x[cd] < T[rt].p.x[cd]) Insert(p, lc, cd^1);
 68     else Insert(p, rc, cd^1);
 69     pushup(rt);
 70 }*/
 71 LL sqr(LL x) {
 72     return x * x;
 73 }
 74 LL dis(Point a,Point b) {
 75     return sqr(a.x[0] - b.x[0]) + sqr(a.x[1] - b.x[1]);
 76 }
 77 LL dist(Point a,KDtree b) {
 78     LL res = 0;
 79     res += max(sqr(a.x[0] - b.mn[0]), sqr(a.x[0] - b.mx[0]));
 80     res += max(sqr(a.x[1] - b.mn[1]), sqr(a.x[1] - b.mx[1]));
 81     return res;
 82 }
 83 void query(Point p,int rt) {
 84     if (!rt) return ;
 85     LL d = dis(T[rt].p,p);
 86     if (d > q.top().dis || (d==q.top().dis && T[rt].p.id < q.top().id)) 
 87         q.pop(), q.push(State(d,T[rt].p.id));
 88     LL dl = lc ? dist(p,T[lc]) : 0; // --- T[rt] !!!
 89     LL dr = rc ? dist(p,T[rc]) : 0; // --- T[rt] !!!
 90     if (dl > dr) {
 91         if (dl >= q.top().dis) query(p,lc);
 92         if (dr >= q.top().dis) query(p,rc);
 93     }
 94     else {
 95         if (dr >= q.top().dis) query(p,rc);
 96         if (dl >= q.top().dis) query(p,lc);
 97     }
 98 }
 99 int main() {
100     int n = read();
101     for (int x,y,i=1; i<=n; ++i) {
102         P[i].x[0] = read(),P[i].x[1] = read(); 
103         P[i].id = i;
104     }
105     Root = build(1,n,0);
106     int m = read();
107     while (m--) {
108         int x = read(),y = read(),k = read();
109         for (int i=1; i<=k; ++i) q.push(State(-INF,0));
110         query(Point(x,y),Root);
111         printf("%d\n",q.top().id);
112         while (!q.empty()) q.pop();
113     }
114     return 0;
115 }

 

posted @ 2018-07-12 07:51  MJT12044  阅读(335)  评论(0编辑  收藏  举报