Kd-tree Getting Started __kd-tree

Source: Internet
Author: User
Tags abs stdin

After a few days of research kd-tree, I can say Kd-tree is to follow the basic ideas casually write on it.

Taking the two-dimensional plane as an example, there are several points on the two-dimensional plane, how do we establish kd-tree?

The first layer divides all the points into two parts in the median of x coordinates, and puts them on the left and right subtree, the second layer in the y-coordinate for the median and then the current set equally, and the third layer is still in the x-coordinate ... So recursively go on.

As an example of querying the nearest point, we find that the query point on the current node should be divided into which subtree. The advantage of traversing this subtree, if the best answer found in this subtree is less than the distance from this point to the dividing line, there is no need to traverse another subtree, which is said to be expected to be O (n^ (D-1)/d), But I don't know why

Three examples inscribed with three different styles of code ...

1, hdu4347

Find the M point nearest to a point in the K-dimensional space, defined as the Euclidean distance.

Kd-tree the basic questions, casually write on it ....

#include <queue> #include <cstdio> #include <vector> #include <cstring> #include <algorithm&

Gt
using namespace Std;
const int MAXN = 100005;
int n,k,q,m,d,i,root;
int son[maxn][2];
  struct point {int x[5];
  void Read () {for (int i=0;i<k;i++) scanf ("%d", &x[i]);
    } void Print () {for (int i=0;i<k-1;i++) printf ("%d", x[i]);
  printf ("%d\n", x[k-1]);
  BOOL operator < (const point &a) const {return x[d] < a.x[d];

}} DOT[MAXN], P;
typedef pair<int,int> PR;
#define DI #define ID second priority_queue <PR> heap;

Vector <int> ans;
  int build (int l,int r,int now) {if (l>r) return 0;
  D = Now;
  int mid = (l+r) >>1;
  Nth_element (dot+l,dot+mid,dot+r+1); L[mid] = l;
  R[mid] = r;
  Son[mid][0] = Build (L,mid-1, (now+1)%k);
  SON[MID][1] = Build (Mid+1,r, (now+1)%k);
return mid;
  #define SQR (x) ((x) * (x)) int Distance (point p1,point P2) {int ret = 0; for (int i=0;i&lT
  k;i++) ret = SQR (p1.x[i]-p2.x[i]);
return ret;
  } void query (int cur,int now) {if (cur==0) return;
  PR nd (Distance (dot[cur],p), cur);
  int x = son[cur][0], y = son[cur][1];
  if (Dot[cur].x[now]<p.x[now]) swap (x,y);
  Query (x, (now+1)%k);
  if (Heap.size () <m) Heap.push (ND);
  else {if (Nd.di 

2, bzoj2648 sjy pendulum pieces

Find the closest point to Manhattan.

Look at the Hzwer program, that Calc judge the query point is closer to that part or more subtle.

But this is a violent insertion. Don't try to rebuild it.

#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int MAXN = 1000005;
const int INF = 1E9;
int n,m,d,ans,root;
int son[maxn][2];
  struct point {int x[2], mn[2], mx[2];
  void Read () {scanf ("%d%d", &x[0],&x[1]);
  BOOL operator < (const point &a) const {return x[d]<a.x[d];

}} DOT[MAXN], P;

int Dis (Point p0,point P1) {return abs (P0.x[0]-p1.x[0]) + ABS (p0.x[1]-p1.x[1]);
  void Update (int p) {Point L = dot[son[p][0]];
  Point R = dot[son[p][1]];
      for (int i=0;i<2;i++) {if (son[p][0]) {dot[p].mn[i]=min (Dot[p].mn[i], l.mn[i]);
    Dot[p].mx[i]=max (Dot[p].mx[i], l.mx[i]);
      } if (son[p][1)) {dot[p].mn[i]=min (Dot[p].mn[i], r.mn[i]);
    Dot[p].mx[i]=max (Dot[p].mx[i], r.mx[i]);
  "}" int build (int l,int r,int now) {if (l>r) return 0;
  D = Now;
  int mid = (l+r) >>1;
  Nth_element (dot+l,dot+mid,dot+r+1); for (int i=0;i<2;i++) dot[Mid].mn[i] = dot[mid].mx[i] = Dot[mid].x[i];
  Son[mid][0] = build (l,mid-1,now^1);
  SON[MID][1] = build (mid+1,r,now^1);
  Update (mid);
return mid;
    } void Insert (int p,int now) {if (Dot[p].x[now]>p.x[now]) {if (son[p][0)) insert (son[p][0],now^1);
      else {son[p][0]=++n;
    for (int i=0;i<2;i++) dot[n].x[i] = dot[n].mn[i] = Dot[n].mx[i] = P.x[i];
    } else {if (son[p][1]) insert (son[p][1],now^1);
      else {son[p][1]=++n;
    for (int i=0;i<2;i++) dot[n].x[i] = dot[n].mn[i] = Dot[n].mx[i] = P.x[i];
} update (P);
  int Calc (point Q) {int ret=0;
    for (int i=0;i<2;i++) {Ret+=max (0,q.mn[i]-p.x[i]);
  Ret+=max (0,p.x[i]-q.mx[i]);
return ret;
  } void query (int p,int now) {int dl=inf, dr=inf;
  Ans=min (ans, Dis (dot[p], p));
  if (Son[p][0]) Dl=calc (dot[son[p][0]);
  if (son[p][1]) Dr=calc (dot[son[p][1]);
    if (DL&LT;=DR) {if (ans>dl) query (son[p][0],now^1); if (ans>dr) query (son[p][1],now^1);
    else {if (ans>dr) query (son[p][1],now^1);
  if (ans>dl) query (son[p][0],now^1);
  int main () {freopen ("2648.in", "R", stdin);
  Freopen ("2648.out", "w", stdout);
  scanf ("%d%d", &n,&m);
  for (int i=1;i<=n;i++) dot[i].read ();
  Root = Build (1,n,0);
    while (m--) {int type;
    scanf ("%d", &type);
    P.read ();
    if (type==1) insert (root,0);
      else {ans = INF;
      Query (root, 0);
    printf ("%d\n", ans);
} return 0; }

3, bzoj4066 simple problem

Look at the topic: This is not CDQ partition.

And then you notice that the space is only 20M.

If you are a card space monster still think this problem can be used CDQ water, you will find this problem forced online ....

The positive solution is kd-tree.

For the problem of the right to point on the board can be directly online maintenance with Kd-tree

But this need to rebuild kd-tree to prevent too whole tree imbalance, you can set a proportional FAC, when the size of a small tree larger than the size of the Shang tree FAC times, the whole Shang tree rebuilt.

I heard someone didn't rebuild the water.

Ask not to say what everybody knows ....

#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int MAXN = 200005;
int x1,x2,y1,y2,d;
int n,n,st,ans,rt;
int son[maxn][2];
int POS[MAXN];
  struct point {int x[2], mn[2], mx[2], W, sum, size;
    void Read () {scanf ("%d%d%d", &x[0],&x[1],&w); X[0]^=ans; X[1]^=ans;
    W^=ans;
    for (int i=0;i<2;i++) mn[i] = mx[i] = X[i]; sum = w;
  size = 1;
  BOOL operator < (const point &a) const {return x[d] < a.x[d];
}} DOT[MAXN];

Const double FAC = 0.65;

BOOL CMP (const int &AMP;A,CONST int &b) {return dot[a].x[d] < dot[b].x[d];
  void Update (int p) {int L = son[p][0], R = son[p][1]; DOT[P].SUM=DOT[P].W;
  dot[p].size=1; Dot[p].sum + = Dot[l].sum;
  Dot[p].size + = Dot[l].size; Dot[p].sum + = Dot[r].sum;
  Dot[p].size + = Dot[r].size;
    for (int i=0;i<2;i++) {Dot[p].mn[i] = dot[p].mx[i] = Dot[p].x[i];
     if (L) {Dot[p].mn[i] = min (Dot[p].mn[i], dot[l].mn[i]); Dot[p].mx[i] = max (Dot[p].mx[i], dot[l].mx[i]);
      } if (R) {Dot[p].mn[i] = min (Dot[p].mn[i], dot[r].mn[i]);
    Dot[p].mx[i] = max (Dot[p].mx[i], dot[r].mx[i]);
  "}" int build (int l,int r,int now) {if (l>r) return 0;
  D = Now;
  int mid = (l+r) >>1;
  Nth_element (POS+L,POS+MID,POS+R+1,CMP);
  Son[pos[mid]][0] = build (l,mid-1,now^1);
  SON[POS[MID]][1] = build (mid+1,r,now^1);
  Update (Pos[mid]);
return Pos[mid];
  } void Dfs (int p) {pos[++st] = p;
  if (Son[p][0]) DFS (son[p][0]);
if (son[p][1]) DFS (son[p][1]);
  int ins (int p,int now) {if (!p) return N;
  int t = (Dot[p].x[now]<=dot[n].x[now]);
    if (Dot[son[p][t]].size+1 > (dot[p].size+1) *fac) {pos[st=1]=n; Dfs (P);
  p = Build (1,st,now);
  else son[p][t] = INS (son[p][t],now^1), update (p);
return p;
  int query (int p,int now) {if (p==0) return 0; if (dot[p].mx[0]<x1| |
  DOT[P].MN[0]&GT;X2) return 0; if (dot[p].mx[1]<y1| |
  Dot[p].mn[1]>y2) return 0; if (dot[P].mn[0]>=x1&&dot[p].mx[0]<=x2&&dot[p].mn[1]>=y1&&dot[p].mx[1]<=y2) return
  Dot[p].sum;
  int ret = 0; if (dot[p].x[0]>=x1&&dot[p].x[0]<=x2&&dot[p].x[1]>=y1&&dot[p].x[1]<=y2) ret +
  = DOT[P].W;
  if (Son[p][0]) ret + query (son[p][0],now^1);
  if (son[p][1]) ret + query (son[p][1],now^1);
return ret;
  int main () {freopen ("4066.in", "R", stdin);
  Freopen ("4066.out", "w", stdout);
  scanf ("%d", &n);
  Ans = 0;
  int type;
      while (~SCANF ("%d", &type)) {if (type==1) {dot[++n].read ();
    RT = INS (rt, 0);
      else if (type==2) {scanf ("%d%d", &x1,&y1); X1 ^= ans;
      Y1 ^= ans;
      scanf ("%d%d", &x2,&y2); X2 ^= ans;
      y2 ^= ans;
      Ans = query (RT, 0);
    printf ("%d\n", ans);
  else break;
return 0; }


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.