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^8的非负整数

    Output

    输出若干行,依次表示每个查询操作的答案。 

    Sample Input

    3
    7 5
    6 2
    3 1
    5
    1 6 1
    1 5 5
    2 7 1
    0 3 2
    1 1 0

    Sample Output

    1
    2
    4
    3
     
    两年前,这道题对于我还是只能仰视的存在,犹记得当时被标算的CDQ分治D飞。
    今天,它成为了kd树模板题。
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define L T[o].lc
    #define R T[o].rc
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    const int BufferSize=1<<16;
    char buffer[BufferSize],*head,*tail;
    inline char Getchar() {
    	if(head==tail) {
    		int l=fread(buffer,1,BufferSize,stdin);
    		tail=(head=buffer)+l;
    	}
    	return *head++;
    }
    inline int read() {
        int x=0,f=1;char c=Getchar();
        for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=200010;
    const int inf=1e9;
    int D,ToT;
    struct Node {
    	int x[2],mx[2],mn[2];
    	int lc,rc;
    	bool operator < (const Node& ths) const {return x[D]<ths.x[D];}
    }T[maxn];
    void maintain(int o) {
    	rep(i,0,1) T[o].mx[i]=max(T[o].x[i],max(T[L].mx[i],T[R].mx[i])),T[o].mn[i]=min(T[o].x[i],min(T[L].mn[i],T[R].mn[i]));
    }
    void build(int& o,int l,int r,int c) {
    	if(l>r) return;int mid=l+r>>1;D=c;o=mid;
    	nth_element(T+l,T+mid,T+r+1);
    	build(L,l,mid-1,c^1);build(R,mid+1,r,c^1);
    	maintain(o);
    }
    Node x;
    void insert(int& o,int c) {
    	if(!o) o=++ToT,T[o]=x;
    	else insert(x.x[c]<=T[o].x[c]?L:R,c^1);
    	maintain(o);
    }
    int ans;
    int dist(Node& a,Node& b) {return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);}
    int calmn(int o) {
    	int res=0;
    	if(x.x[0]<T[o].mn[0]) res+=T[o].mn[0]-x.x[0];
    	if(x.x[0]>T[o].mx[0]) res+=x.x[0]-T[o].mx[0];
    	if(x.x[1]<T[o].mn[1]) res+=T[o].mn[1]-x.x[1];
    	if(x.x[1]>T[o].mx[1]) res+=x.x[1]-T[o].mx[1];
    	return res;
    }
    int calmx(int o) {return max(abs(x.x[0]-T[o].mx[0]),abs(x.x[0]-T[o].mn[0]))+max(abs(x.x[1]-T[o].mx[1]),abs(x.x[1]-T[o].mn[1]));}
    void querymn(int o) {
    	if(!o) return;
    	ans=min(ans,dist(T[o],x));
    	int dl=calmn(L),dr=calmn(R);
    	if(dl<dr) {
    		if(dl<ans) querymn(L);
    		if(dr<ans) querymn(R);
    	}
    	else {
    		if(dr<ans) querymn(R);
    		if(dl<ans) querymn(L);
    	}
    }
    void querymx(int o) {
    	if(!o) return;
    	ans=max(ans,dist(T[o],x));
    	int dl=calmx(L),dr=calmx(R);
    	if(dl>dr) {
    		if(dl>ans) querymx(L);
    		if(dr>ans) querymx(R);
    	}
    	else {
    		if(dr>ans) querymx(R);
    		if(dl>ans) querymx(L);
    	}
    }
    int main() {
    	T[0].mx[0]=T[0].mx[1]=-inf;
    	T[0].mn[0]=T[0].mn[1]=inf;
    	int n=read(),rt=0;ToT=n;
    	rep(i,1,n) T[i].x[0]=read(),T[i].x[1]=read();
    	build(rt,1,n,0);
    	dwn(i,read(),1) {
    		int t=read();x.x[0]=read();x.x[1]=read();
    		if(!t) insert(rt,0);
    		else if(t==1) ans=inf,querymn(rt);
    		else ans=-inf,querymx(rt);
    		if(t) printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    (笔试题)镇长选举
    (笔试题)最小的非“重复的数”
    ( 笔试题)只出现一次的数
    (算法)二叉树中两个结点的最近公共父结点
    (笔试题)区间最大重叠
    (剑指Offer)面试题61:按之字形顺序打印二叉树
    (算法)Partition方法求数组第k大的数
    (剑指Offer)面试题60:把二叉树打印成多行
    整理一些不错的、网上好评的电影、电视、视频等资源地址
    个人网站/博客,建站好的域名和网站供应商网站整理
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5391831.html
Copyright © 2011-2022 走看看