列表

详情


NC213132. QueryofSquare

描述

Bobo has a polygon consisting of n vertices. All sides of the polygon are parallel to the coordinate axes, and each two adjacent sides of the polygon are perpendicular. It is guaranteed that the polygon is simple, that is, it doesn't have self-intersections and self-touches.

Bobo has m queries and in each query, a point (u_i, v_i) strictly inside the polygon is given. Bobo would like to know the length of the maximal square inside the polygon whose lower left corner is (u_i, v_i).

输入描述

The input consists of several test cases terminated by end-of-file. For each test case:

The first line contains two integers n and m, which are the number of vertices and the number of queries.

Each of the next n lines contains two integers x_i and y_i, the coordinates of vertices of the polygon in counterclockwise order.

Each of the next m lines contains two integers u_i and v_i, the coordinates of the lower left corner.

*
*
*
* The sum of n and the sum of m do not exceed .

输出描述

For each query, output an integer denoting the length of the maximal square inside the polygon.

示例1

输入:

4 3
0 0
4 0
4 4
0 4
1 1
2 2
3 3
12 12
3050 2000
2000 2000
2000 3635
-2000 3635
-2000 2000
-2590 2000
-2590 -2000
-2000 -2000
-2000 -3481
2000 -3481
2000 -2000
3050 -2000
1415 -2882
-1100 498
-827 -3331
-114 -542
-1887 3485
-1606 -1463
-768 880
-1261 1180
330 2648
-1017 -2886
-1213 -585
-2025 -1966

输出:

3
2
1
585
3100
2827
2542
150
3606
2755
2455
987
3017
3213
3966

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 3154ms, 内存消耗: 33832K, 提交时间: 2020-11-27 15:46:55

#include<bits/stdc++.h>
#define MM int M=(l+r)>>1;
#define fu(i,r,t) for(int i=r;i<=t;i++)
#define fun(i) fu(i,1,n)
#define fum(i) fu(i,1,m)
using namespace std;
const int INF=2e8+10;
const int maxn=4e5+10;
int n,m,a[maxn],b[maxn];
int Ans[maxn],kinds,Data[maxn];
int ID(int val) { return lower_bound(Data + 1, Data + 1 + kinds, val) - Data; }
int tree_f[maxn];//pos:下标;val:更新的值;up:数组容量上限,一般是n,getsum(n+1)是错误的;
void update(int pos,int val,int up){ for(int i=pos;i<=up;i+=i&-i) if(val<tree_f[i])tree_f[i] = val; }
void Set(int pos,int val,int up){ for(int i=pos;i<=up;i+=i&-i) tree_f[i] = val; }
int getmin(int pos){ int num = INF;for(int i=pos;i;i-=i&-i)if(tree_f[i]<num)num = tree_f[i];return num; }
struct node{
    int y_x,x,_y,type,index,ans;//type=1表示为线段,0为点;
}A[maxn],tmp[maxn];
bool cmp1(node&a,node&b)
{
    if(a.x^b.x)return a.x>b.x;
    else if(a.y_x^b.y_x)return a.y_x<b.y_x;
    else return a._y<b._y;
}
int cnt,cData;
void change(int index,int kind)
{
    if(kind && A[index].type==0)A[index].ans=min(A[index].ans,getmin(A[index]._y)-A[index].x);
    else if(!kind && A[index].type)update(A[index]._y,A[index].x,kinds);
}
void cdq(int l,int r)
{
    if(l==r)return;
    MM
    cdq(l,M),cdq(M+1,r);
    int z=l,y=M+1,cntc=l;
    while(z<=M && y<=r)
    {
        if(A[z].y_x<=A[y].y_x)change(z,0),tmp[cntc++]=A[z++];
        else change(y,1),tmp[cntc++]=A[y++];
    }
    while(z<=M)change(z,0),tmp[cntc++]=A[z++];
    while(y<=r)change(y,1),tmp[cntc++]=A[y++];
    fu(i,l,M)if(A[i].type)Set(A[i]._y,INF,kinds);
    fu(i,l,r)A[i]=tmp[i];
}
void deal()
{
    cnt=0,cData=0;
    fu(i,0,n-1)
    {
        if(a[i]==a[i+1])
        {
            int x=a[i],ymin=min(b[i],b[i+1]),ymax=max(b[i],b[i+1]);
            A[++cnt]={ymin-x,x,-ymax,1,-1,INF};
            Data[++cData]=-ymax;
        }
    }
    fu(i,n+1,n+m)A[++cnt]={b[i]-a[i],a[i],-b[i],0,i-n,INF},Data[++cData]=-b[i];
    sort(Data+1,Data+1+cData);
    kinds=unique(Data+1,Data+1+cData)-Data-1;
    sort(A+1,A+1+cnt,cmp1);
    fu(i,1,cnt)A[i]._y=ID(A[i]._y);
    fu(i,1,kinds)tree_f[i]=INF;
    cdq(1,cnt);
    fu(i,1,cnt)if(!A[i].type && A[i].ans<Ans[A[i].index])Ans[A[i].index]=A[i].ans;
}
template <class T> void read(T &x) {
    int f = 0; x = 0; char ch = getchar();
    for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
    for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    if (f) x = -x;
}
void solve()
{
    fun(i)read(a[i]),read(b[i]);
    a[0]=a[n],b[0]=b[n];
    fum(i)read(a[i+n]),read(b[i+n]),Ans[i]=INF;
    deal();
    fu(i,0,n+m)swap(a[i],b[i]);
    deal();
    fum(i)printf("%d\n",Ans[i]);
    return ;
}
int main()
{
    while(~scanf("%d%d",&n,&m))solve();
    return 0;
}

上一题