P2202 [USACO13JAN] Square Overlap S
分析
如果想让以 和 为中心的两个正方形重叠,那么显而易见 且 。
由于 ,所以 的暴力显然过不去, 放的很宽,根号科技及以下都可以通过,这里提供一个比较暴力的平衡树做法。
将每个点的坐标以横坐标为键值插入 FHQ 后,将原序列按横坐标为关键字从小到大排序。这样就可以直接去 FHQ 里查询后继,如果 就去比对 和 ,之后再判断那三种重叠情况即可。
不知道是不是人傻常数大的缘故,加了从 那里薅来的快读快写跟 inline
等一系列优化才过掉的。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+12;
const int inf=0x3f3f3f3f;
//这个不是Darling_zero_two的快读,是从timedrop那里薅来的
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template<typename T>inline void read(T& t) {
int c=getchar(),f=1;
t=0;
while(!isdigit(c)) {
if(c=='-')f=-1;
c=getchar();
}
while(isdigit(c))t=t*10+c-48,c=getchar();
t*=f;
}
template<typename T,typename ...Args>inline void read(T& t,Args&... args) {
read(t),read(args...);
}
int cnt=0,root=0,rnkx,rnky;
struct noed {
int l,r;
int numx,numy,pri;
int size;
} t[maxn];
struct pos {
int x,y;
} a[maxn];
inline bool cmp(pos x,pos y) {
return x.x<y.x;
}
inline void build(int x,int y) {
cnt++;
t[cnt].size=1;
t[cnt].l=t[cnt].r=0;
t[cnt].numx=x;
t[cnt].numy=y;
t[cnt].pri=rand();
}
inline void split(int p,int x,int &l,int &r) {
if(p==0) {
l=r=0;
return ;
}
if(t[p].numx<=x) {
l=p;
split(t[p].r,x,t[p].r,r);
} else {
r=p;
split(t[p].l,x,l,t[p].l);
}
t[p].size=t[t[p].l].size+t[t[p].r].size+1;
}
inline int merge(int l,int r) {
if(l==0 or r==0)
return l+r;
if(t[l].pri>t[r].pri) {
t[l].r=merge(t[l].r,r);
t[l].size=t[t[l].l].size+t[t[l].r].size+1;
return l;
} else {
t[r].l=merge(l,t[r].l);
t[r].size=t[t[r].l].size+t[t[r].r].size+1;
return r;
}
}
inline void insert(int x,int y) {
int l,r;
split(root,x,l,r);
build(x,y);
int p=merge(l,cnt);
root=merge(p,r);
}
inline int kp(int p,int x) {
int num=t[t[p].l].size;
if(x==num+1)
return p;
if(x<=num)
return kp(t[p].l,x);
if(x>num)
return kp(t[p].r,x-t[t[p].l].size-1);
}
inline void nerv(int x) {
int l,r;
split(root,x,l,r);
int o=kp(r,1);
rnkx=t[o].numx;
rnky=t[o].numy;
root=merge(l,r);
//cout<<" o "<<o<<" x "<<rnkx<<" y "<<rnky<<endl;
}
inline void write(int x) {
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int main() {
int i,n,k;
read(n,k);
insert(inf,inf),insert(-inf,-inf);
for(i=1; i<=n; i++) {
read(a[i].x,a[i].y);
insert(a[i].x,a[i].y);
}
sort(a+1,a+n+1,cmp);
int ans=0;
for(i=1; i<=n; i++) {
nerv(a[i].x);
while(rnkx-a[i].x<k) {
if(abs(rnky-a[i].y)<k) {
if(ans) {
cout<<-1<<endl;
return 0;
}
ans=abs(k-abs(rnkx-a[i].x))*abs(k-abs(rnky-a[i].y));
}
nerv(rnkx);
}
}
cout<<ans;
return 0;
}
备注
-
是从 这篇文章薅来的快读