6
19
2016
0

[BZOJ2648] SJY摆棋子

KD-Tree 模版题

查询最近点在KD树上走一走就行了

注意:此题不需要特别的卡常技巧,基本上写对了就过了(不需要重构子树、加一些玄学科技)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
 
const int N=500005,INF=2100000000;
 
int n,m,Sort_Tag,root,ans=INF;
 
struct KDTree{
int l,r,d[2],mn[2],mx[2];
KDTree(){}
KDTree(int x,int y){mn[0]=mx[0]=d[0]=x;mn[1]=mx[1]=d[1]=y;l=r=0;}
friend bool operator<(KDTree A,KDTree B){return A.d[Sort_Tag]<B.d[Sort_Tag];}
}tree[N<<2],Temp;
 
int Abs(int x){return x>0?x:-x;}
int Dist(KDTree A,KDTree B){return Abs(A.d[0]-B.d[0])+Abs(A.d[1]-B.d[1]);}
 
void Pushup(int rt){
if(tree[rt].l){
    tree[rt].mx[0]=max(tree[rt].mx[0],tree[tree[rt].l].mx[0]);
    tree[rt].mx[1]=max(tree[rt].mx[1],tree[tree[rt].l].mx[1]);
    tree[rt].mn[0]=min(tree[rt].mn[0],tree[tree[rt].l].mn[0]);
    tree[rt].mn[1]=min(tree[rt].mn[1],tree[tree[rt].l].mn[1]);
}
if(tree[rt].r){
    tree[rt].mx[0]=max(tree[rt].mx[0],tree[tree[rt].r].mx[0]);
    tree[rt].mx[1]=max(tree[rt].mx[1],tree[tree[rt].r].mx[1]);
    tree[rt].mn[0]=min(tree[rt].mn[0],tree[tree[rt].r].mn[0]);
    tree[rt].mn[1]=min(tree[rt].mn[1],tree[tree[rt].r].mn[1]);
}
}
 
int Build(int l,int r,int D){
Sort_Tag=D;
int mid=l+r>>1;
nth_element(tree+l,tree+mid,tree+r+1);
tree[mid].mn[0]=tree[mid].mx[0]=tree[mid].d[0];
tree[mid].mn[1]=tree[mid].mx[1]=tree[mid].d[1];
if(l<mid)tree[mid].l=Build(l,mid-1,!D);
if(r>mid)tree[mid].r=Build(mid+1,r,!D);
Pushup(mid);
return mid;
}
 
void _Insert(int rt,int D){
if(Temp.d[D]>=tree[rt].d[D]){
    if(tree[rt].r)_Insert(tree[rt].r,!D);
    else {tree[rt].r=++n;tree[n]=Temp;}
}
else {
    if(tree[rt].l)_Insert(tree[rt].l,!D);
    else {tree[rt].l=++n;tree[n]=Temp;}
}
Pushup(rt);
}
 
void Insert(int x,int y){
Temp=KDTree(x,y);
_Insert(root,0);
}
 
int MxDist(int rt,int x,int y){
return max(tree[rt].mn[0]-x,0)+max(x-tree[rt].mx[0],0)+max(tree[rt].mn[1]-y,0)+max(y-tree[rt].mx[1],0);
}
 
void _Query(int rt){
int Dl=INF,Dr=INF,Dm=Dist(tree[rt],Temp);
ans=min(ans,Dm);
if(tree[rt].l)Dl=MxDist(tree[rt].l,Temp.d[0],Temp.d[1]);
if(tree[rt].r)Dr=MxDist(tree[rt].r,Temp.d[0],Temp.d[1]);
if(Dl<Dr){
    if(Dl<ans)_Query(tree[rt].l);
    if(Dr<ans)_Query(tree[rt].r);
}
else {
    if(Dr<ans)_Query(tree[rt].r);
    if(Dl<ans)_Query(tree[rt].l);
}
}
 
int Query(int x,int y){
Temp=KDTree(x,y);ans=INF;
_Query(root);
return ans;
}

int main(){
freopen("2648.in","r",stdin);
freopen("2648.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d %d",&tree[i].d[0],&tree[i].d[1]);
root=Build(1,n,0);
for(int i=1;i<=m;i++){
    int opt,x,y;
    scanf("%d %d %d",&opt,&x,&y);
    if(opt==1)Insert(x,y);
    if(opt==2)printf("%d\n",Query(x,y));
}
return 0;
}
Category: BZOJ | Tags: OI bzoj | Read Count: 441

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com