您的位置:首页 > 其它

BZOJ 2648 SJY摆棋子(KD Tree)

2017-10-19 20:13 381 查看
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
.d[0]=t
.MAX[0]=t
.MIN[0]=x;
t
.d[1]=t
.MAX[1]=t
.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: