NC213132. QueryofSquare
描述
输入描述
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 and , the coordinates of vertices of the polygon in counterclockwise order.
Each of the next m lines contains two integers and , 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; }