BZOJ 1941: [Sdoi2010]Hide and Seek(k-d Tree)

Keywords: C++ PHP

Time Limit: 16 Sec  Memory Limit: 162 MB
Submit: 1712  Solved: 932
[Submit][Status][Discuss]

Description

Little pig iPig has just finished the boring pig algebra class in PKU. The talented iPig is very lonely by this door to his extremely simple lesson. In order to eliminate loneliness, he decides to play a more lonely game with his good friend giPi (chicken skin) --- hide and seek. However, they feel that playing ordinary hide-and-seek is not interesting, or not lonely enough, so they decided to play the lonely crab version of hide-and-seek, as the name implies, that is, they can only play the game along the horizontal or vertical direction. After a lonely pair of scissors and stone cloth, they decided that the iPig would catch giPi. Because they are all familiar with the topography of PKU, giPi will only hide in n hidden locations within the PKU, and apparently the iPig will only find giPi in those locations. At the beginning of the game, they chose a location where the iPig stayed motionless, and giPi fled the scene in 30 seconds (apparently, giPi would not stay in place). The iPig then randomly searches for giPi until it finds it. Because the iPig is lazy, he always takes the shortest route to get there, and he doesn't choose the starting point at random. He wants to find a place where the distance between the farthest place and the nearest place is the smallest. The iPig now wants to know what the smallest distance difference is. Because the iPig doesn't have a computer now, it can't program to solve such a simple problem, so he immediately called to ask you to help him solve the problem. The iPig tells you the coordinates of the N hidden locations of the PKU. Please program to solve the problem of the iPig.

Input

The first line inputs an integer N, lines 2 to N + 1, two integers X, Y for each line, representing the coordinates of the location i.

Output

An integer is the minimum of the distance difference.

Sample Input

4
0 0
1 0
0 1
1 1

Sample Output

1

HINT

 

For 30% data, N<=1000 for 100% data, N<=500000, 0<=X, Y<=10^ 8 guarantees that data does not focus on N>=2.

 

Source

SDOI 2010 Second Round Day 1

 
K-D Tree bare questions, no deletion and insertion
I tried to write it myself.
After opening O2 on Luogu, WA T
Lose all standing and reputation
 
#include<cstdio>
#include<algorithm>
//#define int long long 
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
using namespace std;
const int MAXN = 200001, INF = 1e9 + 10;
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N;
int WD = 0, cur = 0, root;
#define ls(k) T[k].ls
#define rs(k) T[k].rs
struct Point {
    int x[2];
    bool operator < (const Point &rhs) const {
        return x[WD] < rhs.x[WD];
    }
}p[MAXN];
struct Node {
    int mi[2], mx[2], ls, rs;
    Point tp;
}T[MAXN];
int NewNode() {
    return ++cur;
}
void update(int k) {
    for(int i = 0; i <= 1; i++) {
        T[k].mi[i] = T[k].mx[i] = T[k].tp.x[i];
        if(ls(k)) T[k].mi[i] = min(T[ls(k)].mi[i], T[k].mi[i]), T[k].mx[i] = max(T[k].mx[i], T[ls(k)].mx[i]);
        if(rs(k)) T[k].mi[i] = min(T[rs(k)].mi[i], T[k].mi[i]), T[k].mx[i] = max(T[k].mx[i], T[rs(k)].mx[i]);
    }
}
int Build(int l, int r, int wd) {
    if(l > r) return 0;
    int k = NewNode(), mid = l + r >> 1;
    WD = wd;
    nth_element(p + l, p + mid, p + r + 1);
    T[k].tp = p[mid];
    T[k].ls = Build(l, mid - 1, wd ^ 1);
    T[k].rs = Build(mid + 1, r, wd ^ 1);
    update(k);
    return k;
}
int Ans;
int dis(Point a, Point b) {//Manhattan Distance 
    return abs(a.x[0] - b.x[0]) + abs(a.x[1] - b.x[1]);
}
int GetMinDis(Point a, Node b) {// Minimum Manhattan Distance from Point to Matrix 
    int rt = 0;
    for(int i = 0; i <= 1; i++)     
        rt += max(0, a.x[i] - b.mx[i]) + max(0, b.mi[i] - a.x[i]);
    return rt;
}
int GetMaxDis(Point a, Node b) {//Maximum Manhattan Distance 
    int rt = 0;
    for(int i = 0; i <= 1; i++)
        rt += max( max(0, a.x[i] - b.mi[i]), max(0, b.mx[i] - a.x[i]) );
        //rt += max(abs(a.x[i] - b.mi[i]), abs(a.x[i] - b.mx[i]));
    return rt;
}
int QueryMax(int k, Point a) {
    Ans = max(Ans, dis(a, T[k].tp));
    int disl = -INF, disr = -INF;
    if(ls(k)) disl = GetMaxDis(a, T[ls(k)]); 
    if(rs(k)) disr = GetMaxDis(a, T[rs(k)]);
    if(disl > disr) {
        if(disl > Ans) Ans = QueryMax(ls(k), a);
        if(disr > Ans) Ans = QueryMax(rs(k), a);
    }
    else {
        if(disr > Ans) Ans = QueryMax(rs(k), a);
        if(disl > Ans) Ans = QueryMax(ls(k), a);
    }
}
int QueryMin(int k, Point a) {
    int tmp = dis(a, T[k].tp);
    if(tmp) Ans = min(Ans, tmp);
    int disl = INF, disr = INF;
    if(ls(k)) disl = GetMinDis(a, T[ls(k)]); 
    if(rs(k)) disr = GetMinDis(a, T[rs(k)]);
    if(disl < disr) {
        if(disl < Ans) Ans = QueryMin(ls(k), a);
        if(disr < Ans) Ans = QueryMin(rs(k), a);
    }
    else {
        if(disr < Ans) Ans = QueryMin(rs(k), a);
        if(disl < Ans) Ans = QueryMin(ls(k), a);
    }
}
main() {
    #ifdef WIN32
    freopen("a.in", "r", stdin);
    #endif
    N = read();
    for(int i = 1; i <= N; i++) p[i].x[0] = read(), p[i].x[1] = read();
    root = Build(1, N, 0);
    int ans = INF, ans1 = 0, ans2 = 0;
    for(int i = 1; i <= N; i++) {
        ans1 = 0, ans2 = 0;
        Ans = -INF; 
        QueryMax(root, p[i]); 
        ans1 = Ans;
        Ans = INF;  
        QueryMin(root, p[i]); 
        ans2 = Ans;
    //    printf("%d %d\n", ans1, ans2);
        ans = min(ans, ans1 - ans2);
    }
    printf("%d", ans);
}

 

Posted by spacee on Mon, 17 Dec 2018 11:48:03 -0800