BZOJ 2648 SJY摆棋子(KD Tree)

http://www.lydsy.com/JudgeOnline/problem.php?id=2648

题意:

 

思路:

KDtree模板题。

参考自http://www.cnblogs.com/rayrayrainrain/p/6349899.html

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = 300000+5;

int x,y;
int n,m;
int ans;
int cmp_d,root;

struct node
{
    int d[2],MAX[2],MIN[2];
    int l,r;
}t[1000005];

bool cmp(node a, node b)
{
    return a.d[cmp_d]<b.d[cmp_d]||a.d[cmp_d]==b.d[cmp_d] && a.d[cmp_d^1] < b.d[cmp_d^1];
}

void PushUp(int p,int k)
{
    t[p].MAX[0]=max(t[p].MAX[0],t[k].MAX[0]);
    t[p].MAX[1]=max(t[p].MAX[1],t[k].MAX[1]);
    t[p].MIN[0]=min(t[p].MIN[0],t[k].MIN[0]);
    t[p].MIN[1]=min(t[p].MIN[1],t[k].MIN[1]);
}


int build(int l,int r, int D)
{
    int mid = (l+r) >> 1;
    cmp_d = D;
    nth_element(t+l+1,t+mid+1,t+r+1,cmp) ;
    t[mid].MAX[0] = t[mid].MIN[0] = t[mid].d[0];
    t[mid].MAX[1] = t[mid].MIN[1] = t[mid].d[1];
    if(l!=mid) t[mid].l = build(l,mid-1,D^1) ;
    else t[mid].l = 0;
    if(r!=mid) t[mid].r = build(mid+1,r,D^1);
    else t[mid].r = 0;
    if(t[mid].l) PushUp(mid,t[mid].l);
    if(t[mid].r) PushUp(mid,t[mid].r);
    return mid ;
}


void update(int k)
{
    int p = root ;
    int D = 0 ;
    while(true)
    {
        PushUp(p,k);
        if(t[k].d[D] <= t[p].d[D])
        {
            if(!t[p].l)
            {
                t[p].l = k ;
                return;
            }
            p = t[p].l ;
        }
        else
        {
            if(!t[p].r){
                t[p].r = k ;
                return;
            }
            p = t[p].r ;
        }
        D ^= 1;
    }
}

int getdis(int p,int x,int y)
{
    int res = 0;
    if(x > t[p].MAX[0])res += x - t[p].MAX[0];
    if(x < t[p].MIN[0])res += t[p].MIN[0] - x;
    if(y > t[p].MAX[1])res += y - t[p].MAX[1];
    if(y < t[p].MIN[1])res += t[p].MIN[1] - y;
    return res ;
}


void query(int p)
{
    int d0 = abs(x - t[p].d[0]) + abs(y - t[p].d[1]) ;
    if(d0<ans) ans = d0 ;
    int dl , dr ;
    if(t[p].l) dl=getdis(t[p].l,x,y) ; else dl = INF ;
    if(t[p].r) dr=getdis(t[p].r,x,y) ; else dr = INF ;
    if(dl < dr)
    {
        if(dl < ans) query(t[p].l) ;
        if(dr < ans) query(t[p].r) ;
    }
    else
    {
        if(dr < ans) query(t[p].r) ;
        if(dl < ans) query(t[p].l) ;
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n ; i ++ )
        scanf("%d%d",&t[i].d[0] , &t[i].d[1]);
    if(n) root = build(1,n,0) ;
    for(int i = 1; i <= m ; i ++ )
    {
        int q; scanf("%d%d%d",&q,&x,&y);
        if(q == 1)
        {
            n++ ;
            t[n].d[0]=t[n].MAX[0]=t[n].MIN[0]=x;
            t[n].d[1]=t[n].MAX[1]=t[n].MIN[1]=y;
            if(n>1) update(n);
            else  root = build(1,n,0);
        }
        else
        {
            ans = INF;
            query(root);
            printf("%d\n",ans);
        }
    }
    return 0;
}

  

 

posted @ 2017-10-19 20:13  Kayden_Cheung  阅读(175)  评论(0编辑  收藏  举报
//目录