单调队列 A
题面去内网找
很明显正解要二分答案,如何高效率地check呢
1.搞一发线段树。
2.单调队列。
题挺水的,但是该复习一下单调队列了。
#include <cstdio>
#define N 100005
int read()
{
int sum=0,f=1;char x=getchar();
while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
while(x>='0'&&x<='9'){sum=(sum<<3)+(sum<<1)+x-'0';x=getchar();}
return sum*f;
}
int x,y,z,ans,y1_[N],y2_[N],z1[N],z2[N];
int h[5],t[5],q[5][N];
bool check(int mid)
{
for(int i=1;i<=4;i++)h[i]=1,t[i]=0;
for(int i=1;i<=x;i++)
{
while(h[1]<=t[1]&&y1_[q[1][t[1]]]<=y1_[i])t[1]--;q[1][++t[1]]=i;
while(h[2]<=t[2]&&y2_[q[2][t[2]]]>=y2_[i])t[2]--;q[2][++t[2]]=i;
while(h[3]<=t[3]&&z1[q[3][t[3]]]<=z1[i])t[3]--;q[3][++t[3]]=i;
while(h[4]<=t[4]&&z2[q[4][t[4]]]>=z2[i])t[4]--;q[4][++t[4]]=i;
while(h[1]<=t[1]&&q[1][h[1]]<=i-mid)h[1]++;
while(h[2]<=t[2]&&q[2][h[2]]<=i-mid)h[2]++;
while(h[3]<=t[3]&&q[3][h[3]]<=i-mid)h[3]++;
while(h[4]<=t[4]&&q[4][h[4]]<=i-mid)h[4]++;
if(i>=mid&&y2_[q[2][h[2]]]-y1_[q[1][h[1]]]+1>=mid&&z2[q[4][h[4]]]-z1[q[3][h[3]]]+1>=mid)return 1;
}
return 0;
}
int main()
{
x=read();y=read();z=read();
for(int i=1;i<=x;i++)
y1_[i]=read(),z1[i]=read(),y2_[i]=read(),z2[i]=read();
int l=1,r=x,mid;
while(l<=r)
{
mid=l+r>>1;
if(check(mid))l=mid+1;
else r=mid-1;
}
printf("%d\n",l-1);
}