zoukankan      html  css  js  c++  java
  • bzoj4533 [BeiJing2014 WinterCamp] 数据

    Description

    为了写论文,Alex经常要整理大量的数据。 这一次,Alex面临一个严峻的考验:他需要实现一个数据结构来维护一个点集。 
    现在,二维平面上有N个点。Alex 需要实现以下三种操作: 
    1. 在点集里添加一个点; 
    2. 给出一个点,查询它到点集里所有点的曼哈顿距离的最小值; 
    3. 给出一个点,查询它到点集里所有点的曼哈顿距离的最大值。 
    两个点的曼哈顿距离定义为它们的横坐标差的绝对值与纵坐标差的绝对值的和。这么困难的问题,Alex当然不会做,只好再次请你帮忙了。 

    Input

    第一行包含一个整数N,表示点集最初的点数。 
    接下来N行,每行两个整数,依次表示每个点的横坐标和纵坐标。 
    第N+2行包含一个整数Q,表示询问的数目。 
    接下来Q行,每行三个整数,依次表示询问的类型,点的横坐标和纵坐标。0类型表示添加一个点,1类型表示查询到该点的曼哈顿距离的最小值,2类型表示查询最大值。 
    1 ≤ N, Q ≤ 100,000,点的坐标是不超过10^9的非负整数

    Output

    输出若干行,依次表示每个查询操作的答案。 
    将点集所有点预处理建成二维kd树,即可查询最近/远点对。
    每次插入点时可以自底向上修改。
    #include<cstdio>
    #include<algorithm>
    const int inf=2147483647;
    inline int read(){
        int x=0,c=getchar();
        while(c>57||c<48)c=getchar();
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x;
    }
    int ans,X[2];
    inline void mins(int&a,int b){if(a>b)a=b;}
    inline void maxs(int&a,int b){if(a<b)a=b;}
    inline int max(int a){return a>0?a:0;}
    struct node{
        int x[2],mn0,mn1,mx0,mx1,id,d,sz;
        node*c0,*c1,*f;
        inline void set(int x1,int x2,int i){
            x[0]=x1;
            x[1]=x2;
            mn0=mn1=inf;
            mx0=mx1=-1;
            id=i;
            sz=d=0;
        }
        inline void upd(int x1,int x2){
            mins(mn0,x1);
            mins(mn1,x2);
            maxs(mx0,x1);
            maxs(mx1,x2);
            ++sz;
        }
        inline int minv(){
            if(!this||!sz)return inf;
            return max(mn0-X[0])+max(X[0]-mx0)+max(mn1-X[1])+max(X[1]-mx1);
        }
        inline int maxv(){
            if(!this||!sz)return -1;
            return max(X[0]-mn0)+max(mx0-X[0])+max(X[1]-mn1)+max(mx1-X[1]);
        }
        void getmin(){
            int a1=inf,a2=inf;
            if(d)mins(ans,abs(x[0]-X[0])+abs(x[1]-X[1]));
            mins(a1,c0->minv());
            mins(a2,c1->minv());
            if(a1<a2){
                if(a1<ans)c0->getmin();
                if(a2<ans)c1->getmin();
            }else{
                if(a2<ans)c1->getmin();
                if(a1<ans)c0->getmin();
            }
        }
        void getmax(){
            int a1=-1,a2=-1;
            if(d)maxs(ans,abs(x[0]-X[0])+abs(x[1]-X[1]));
            maxs(a1,c0->maxv());
            maxs(a2,c1->maxv());
            if(a1>a2){
                if(a1>ans)c0->getmax();
                if(a2>ans)c1->getmax();
            }else{
                if(a2>ans)c1->getmax();
                if(a1>ans)c0->getmax();
            }
        }
    }ns[200005],*rt,*ids[200005];
    int dx=0;
    bool operator<(const node&a,const node&b){
        if(a.x[dx]!=b.x[dx])return a.x[dx]<b.x[dx];
        return a.x[dx^1]<b.x[dx^1];
    }
    int n,q,p;
    int qo[100005],qx[100005],qy[100005];
    node*build(node*l,node*r){
        if(l==r)return 0;
        node*m=l+(r-l>>1);
        std::nth_element(l,m,r);
        dx^=1;
        m->c0=build(l,m);
        m->c1=build(m+1,r);
        if(m->c0)m->c0->f=m;
        if(m->c1)m->c1->f=m;
        dx^=1;
        return m;
    }
    void ins(node*w){
        w->d=1;
        int x1=w->x[0],x2=w->x[1];
        for(;w;w=w->f)w->upd(x1,x2);
    }
    int main(){
        n=read();
        for(int i=0,x,y;i<n;i++){
            x=read();y=read();
            ns[i].set(x,y,i);
        }
        q=read();
        p=n;
        for(int i=0,o,x,y;i<q;i++){
            o=read();x=read();y=read();
            qo[i]=o;qx[i]=x;qy[i]=y;
            if(o==0)ns[p++].set(x,y,n+i);
        }
        rt=build(ns,ns+p);
        for(int i=0;i<p;i++)ids[ns[i].id]=ns+i;
        for(int i=0;i<n;i++)ins(ids[i]);
        for(int i=0;i<q;i++){
            int o=qo[i];
            X[0]=qx[i];X[1]=qy[i];
            if(o==0)ins(ids[n+i]);
            else if(o==1){
                ans=inf;
                rt->getmin();
                printf("%d
    ",ans);
            }else{
                ans=-1;
                rt->getmax();
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    动画编程1
    驾照助手
    《机器学习进阶》Udacity 机器学习基础 决策树+迷你项目
    《机器学习进阶》Udacity 机器学习基础 异常值+交叉验证
    《机器学习进阶》Udacity 机器学习基础 评估指标
    《机器学习进阶》Udacity 监督学习 决策树
    《机器学习进阶》Udacity 监督学习 SVM支持向量机
    入门模拟(图形输出)——B1036.跟奥巴马一起编程( 注意行数为偶数或奇数的情况)
    入门模拟——A1036.Boys vs Girls
    leetcode 深搜广搜
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5397057.html
Copyright © 2011-2022 走看看