BZOJ_P2648 SJY摆棋子&BZOJ_P2716 [Violet 3]天使玩偶(KD-Tree)

BZOJ_P2648
BZOJ_P2716
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 1980 Solved: 659
[Submit][Status][Discuss]
Description
这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。

Input
第一行两个数 N M
以后M行,每行3个数 t x y
如果t=1 那么放下一个黑色棋子
如果t=2 那么放下一个白色棋子

Output
对于每个T=2 输出一个最小距离

Sample Input
2 3
1 1
2 3
2 1 2
1 3 3
2 4 2

Sample Output
1
2

HINT
kdtree可以过

Source
鸣谢 孙嘉裕

双倍经验,两道题一毛一样。
KD-Tree模板题

#include
#include
#include
#include
#include
using namespace std;
#define N 500005
#define INF 0x7fffffff
#define lc p[o].ch[0]
#define rc p[o].ch[1]
inline int in(int x=0,char ch=getchar(),int v=1){
    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();if(ch=='-') v=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*v;}

struct Node{int d[2],mi[2],ma[2],ch[2];}p[N<<1],now;
int n,m,D,cnt,root,ans;
inline int cmp(Node a,Node b){return a.d[D]int o){
    p[o].mi[0]=min(p[o].d[0],min(p[lc].mi[0],p[rc].mi[0]));
    p[o].mi[1]=min(p[o].d[1],min(p[lc].mi[1],p[rc].mi[1]));
    p[o].ma[0]=max(p[o].d[0],max(p[lc].ma[0],p[rc].ma[0]));
    p[o].ma[1]=max(p[o].d[1],max(p[lc].ma[1],p[rc].ma[1]));
}
inline int dis(Node a,Node b){return fabs(a.d[0]-b.d[0])+fabs(a.d[1]-b.d[1]);}
void Build(int &o,int l,int r,int d){
    D=d,o=(l+r)>>1;nth_element(p+l,p+o,p+r+1,cmp);
//  for(int i=1;i<=n;i++) printf("%d %d\n",p[i].d[0],p[i].d[1]);
    if(llc,l,o-1,d^1);if(r>o) Build(rc,o+1,r,d^1);
    push_up(o);
}
void insert(int &o,int d){
    if(!o) o=++cnt,p[o]=now;
    else if(now.d[d]lc,d^1);
    else insert(rc,d^1);
    push_up(o);
}
int Calc(int o){
    return max(p[o].mi[0]-now.d[0],0)+max(now.d[0]-p[o].ma[0],0)+
            max(p[o].mi[1]-now.d[1],0)+max(now.d[1]-p[o].ma[1],0);
}
void Query(int o){
    if(!o) return;
    ans=min(ans,dis(p[o],now));
    int ll=INF,rr=INF;
    if(lc) ll=Calc(lc);if(rc) rr=Calc(rc);
    if(llif(lllc);
        if(rrelse{
        if(rrif(lllc);
    }
}
int main(){
    p[0].ma[0]=p[0].ma[1]=-INF;
    p[0].mi[0]=p[0].mi[1]=INF;
    cnt=n=in(),m=in();
    for(int i=1;i<=n;i++) p[i].d[0]=in(),p[i].d[1]=in();
    Build(root,1,n,0);int x;
    while(m--){
        x=in(),now.d[0]=in(),now.d[1]=in();
        if(x==1) insert(root,0);
        else ans=INF,Query(root),printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(BZOJ,KD-Tree)