description
2034年,纪念中学决定修建校庆100周年纪念碑,作为杰出校友的你被找了过来,帮校方确定纪念碑的选址.
纪念中学的土地可以看作是一个长为n,宽为m的矩形.它由n* m个1*1的正方形组成,其中左下角的正方形的坐标为(1,1),右上角的正方形的坐标为(n, m).其中有一些土地已经被用来修建建筑物,每一幢建筑物都可以看做是一个左下角为(x1,y1),右上角为(x2,y2)的矩形.
纪念碑可以看作是一个正方形.校方希望你找出一块最大的正方形区域供他们参考.
analysis
-
听说是很套路的线段树+++扫描线
-
主要还是把矩形拆成x1x1x1的插入操作和x2+1x2+1x2+1的删除操作
-
把操作按xxx排序,用两个指针l,rl,rl,r扫区间,用线段树最大空长度
-
当r−l+1r-l+1r−l+1大于最大空长度就右移lll,否则右移rrr
code
-
其实我还是不怎么会扫描线……
-
这个标是我对着标打的以后我学了扫描线就把这个小坑填了(FLAG)
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 1000005
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))
using namespace std;
ll n,m,p,tot,ans;
struct node
{
ll x,y1,y2,z;
}a[MAXN<<1];
struct point
{
ll l,r,c,mx;
}tr[MAXN<<2];
O3 inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
O3 inline ll max(ll x,ll y)
{
return x>y?x:y;
}
O3 inline ll min(ll x,ll y)
{
return x<y?x:y;
}
O3 inline bool cmp(node a,node b)
{
return a.x<b.x;
}
O3 inline void update(ll t,ll l,ll r)
{
ll mid=(l+r)>>1;
tr[t].l=tr[t<<1].l,tr[t].r=tr[t<<1|1].r;
if (tr[t<<1].l==mid-l+1)tr[t].l+=tr[t<<1|1].l;
if (tr[t<<1|1].r==r-mid)tr[t].r+=tr[t<<1].r;
tr[t].mx=max(tr[t<<1].mx,tr[t<<1|1].mx);
tr[t].mx=max(tr[t].mx,tr[t<<1].r+tr[t<<1|1].l);
}
O3 inline void maketree(ll t,ll l,ll r)
{
tr[t].mx=tr[t].l=tr[t].r=r-l+1;
if (l==r)return;
ll mid=(l+r)>>1;
maketree(t<<1,l,mid),maketree(t<<1|1,mid+1,r);
}
O3 inline void change(ll t,ll l,ll r,ll x,ll y,ll z)
{
if (l==x && y==r)
{
tr[t].c+=z;
if (tr[t].c==0)
{
if (l==r)tr[t].mx=tr[t].l=tr[t].r=1;
else update(t,l,r);
}
else tr[t].mx=tr[t].l=tr[t].r=0;
return;
}
ll mid=(l+r)>>1;
if (y<=mid)change(t<<1,l,mid,x,y,z);
else if (x>mid)change(t<<1|1,mid+1,r,x,y,z);
else change(t<<1,l,mid,x,mid,z),change(t<<1|1,mid+1,r,mid+1,y,z);
if (tr[t].c==0)update(t,l,r);
else tr[t].mx=tr[t].l=tr[t].r=0;
}
O3 int main()
{
//freopen("T1.in","r",stdin);
n=read(),m=read(),p=read();
fo(i,1,p)
{
ll x1=read(),y1=read(),x2=read(),y2=read();
a[++tot].x=x1,a[tot].y1=y1,a[tot].y2=y2,a[tot].z=1;
a[++tot].x=x2+1,a[tot].y1=y1,a[tot].y2=y2,a[tot].z=-1;
}
sort(a+1,a+tot+1,cmp);
maketree(1,1,m);
ll l=1,r=1,nl=1,nr=1;
while (a[nl].x==l)
{
if (a[nl].z==-1)change(1,1,m,a[nl].y1,a[nl].y2,a[nl].z);
++nl;
}
while (a[nr].x==r)
{
if (a[nr].z==1)change(1,1,m,a[nr].y1,a[nr].y2,a[nr].z);
++nr;
}
while (r<=n)
{
ans=max(ans,min(tr[1].mx,r-l+1));
if (r-l+1<=tr[1].mx)
{
++r;
while (a[nr].x==r)
{
if (a[nr].z==1)change(1,1,m,a[nr].y1,a[nr].y2,a[nr].z);
++nr;
}
}
else
{
++l;
while (a[nl].x==l)
{
if (a[nl].z==-1)change(1,1,m,a[nl].y1,a[nl].y2,a[nl].z);
++nl;
}
}
}
printf("%lld\n",ans);
return 0;
}