Zoning Houses 线段树 North American Invitational Programming Contest 2018

Given a registry of all houses in your state or province, you would like to know the minimum size of an axis-aligned square zone such that every house in a range of addresses lies in the zone or on its border. The zoning is a bit lenient and you can ignore any one house from the range to make the zone smaller.

The addresses are given as integers from 1..n. Zoning requests are given as a consecutive range of houses. A valid zone is the smallest axis-aligned square that contains all of the points in the range, ignoring at most one.

Given the (x,y) locations of houses in your state or province, and a list of zoning requests, you must figure out for each request: What is the length of a side of the smallest axis-aligned square zone that contains all of the houses in the zoning request, possibly ignoring one house?

Input
Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. Each test case will begin with a line containing two integers n and q (1≤n,q≤105), where n is the number of houses, and q is the number of zoning requests.

The next n lines will each contain two integers, x and y (109≤x,y≤109), which are the (x,y) coordinates of a house in your state or province. The address of this house corresponds with the order in the input. The first house has address 1, the second house has address 2, and so on. No two houses will be at the same location.

The next q lines will contain two integers a and b (1≤a<b≤n), which represents a zoning request for houses with addresses in the range [a..b] inclusive.

Output
Output q lines. On each line print the answer to one of the zoning requests, in order: the side length of the smallest axis-aligned square that contains all of the points of houses with those addresses, if at most one house can be ignored.

Sample Input 1	Sample Output 1
3 2
1 0
0 1
1000 1
1 3
2 3
1
0
Sample Input 2	Sample Output 2
4 2
0 0
1000 1000
300 300
1 1
1 3
2 4
300
299

题目大意:
给你n个二维的点,给你q个询问,问你Ll到R这些点中,用一个最小的正方形盖住需要的最小边长,你可以舍弃其中的一个点。
分析
这样的话,可以用线段树记录X与Y最大,最小,次大,次小,借鉴了其他人的代码,自己写的。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef pair<int,int>P;
int n,q;
const int maxn = 100000 + 10;
P ma[maxn<<2][4];
struct node
{
    int x,y;
}s[maxn];
const int INF=2e9+7;
void pushup(int o)
{
    for(int i=0;i<4;i++)
    {
        ma[o][i]=max(ma[o<<1][i],ma[o<<1|1][i]);
    }
}
void build(int o,int L,int R)
{
    //cout<
    if(L==R)
    {
        ma[o][0]=make_pair(s[L].x,L);
        ma[o][1]=make_pair(-s[L].x,L);
        ma[o][2]=make_pair(s[L].y,L);
        ma[o][3]=make_pair(-s[L].y,L);
        return ;
    }
    int mid=L+R>>1;
    build(o<<1,L,mid);
    build(o<<1|1,mid+1,R);
    pushup(o);
}
P query(int o,int L,int R,int l,int r,int op)
{
    //cout<
    if(l<=L&&r>=R)
    {
        return ma[o][op];
    }
    int mid=L+R>>1;
    if(l<=mid&&r>mid)
    {
        return max(query(o<<1,L,mid,l,r,op),query(o<<1|1,mid+1,R,l,r,op));
    }
    if(r<=mid)
    {
        return query(o<<1,L,mid,l,r,op);
    }
    if(l>mid)
    {
        return query(o<<1|1,mid+1,R,l,r,op);
    }
    
}
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&s[i].x,&s[i].y);
    }
    build(1,1,n);
    int x,y;
    for(int i=0;i<q;i++)
    {
        scanf("%d%d",&x,&y);
        if(x==y)
        {
            printf("0\n"); continue;
        }
        int ans=INF;
        for(int j=0;j<4;j++)
        {
            P temp=query(1,1,n,x,y,j);
            int pos=temp.second;
            int dx=-INF,dy=-INF;
            int mx=INF,my=INF;
            if(x<pos)
            {
                temp=query(1,1,n,x,pos-1,0);
                dx=max(dx,temp.first);
                temp=query(1,1,n,x,pos-1,1);
                mx=min(mx,-temp.first);
                temp=query(1,1,n,x,pos-1,2);
                dy=max(dy,temp.first);
                temp=query(1,1,n,x,pos-1,3);
                my=min(my,-temp.first);
            }
            if(pos<y)
            {
                temp=query(1,1,n,pos+1,y,0);
                dx=max(dx,temp.first);
                temp=query(1,1,n,pos+1,y,1);
                mx=min(mx,-temp.first);
                temp=query(1,1,n,pos+1,y,2);
                dy=max(dy,temp.first);
                temp=query(1,1,n,pos+1,y,3);
                my=min(my,-temp.first);
            }
            ans=min(ans,max(dx-mx,dy-my));
        }
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(数据结构)