bzoj 4951: [Wf2017]Money for Nothing【分治】

参考:https://blog.csdn.net/herobrine_tkj/article/details/78404426?locationNum=8&fps=1
为什么从1开始存就挂了,这是个未解之谜...
把两个人条件转换为二维平面内的点,零件生产公司是左下角,零件消费公司是右上角,求最大矩形
然后画图可知这个是单调的,所以把零件生产公司和零件消费公司一起分治即可
注意一开始要x-y排序之后去重,保持x和y的单调

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=500005;
int n,m;
bool del[N];
struct qwe
{
	int x,y;
}a[N],b[N];
bool cmp(const qwe &a,const qwe &b)
{
	return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int read()
{
	int r=0,f=1;
	char p=getchar();
	while(p>'9'||p<'0')
	{
		if(p=='-')
			f=-1;
		p=getchar();
	}
	while(p>='0'&&p<='9')
	{
		r=r*10+p-48;
		p=getchar();
	}
	return r*f;
}
int pre(qwe*a,int n,int type)
{
    sort(a,a+n,cmp);
    memset(del,0,sizeof(del));
    if(type==0)
    {
        int la=0;
        for(int i=1;i<n;i++)
        {
            if(a[i].y>=a[la].y)
				del[i]=1;
            else
				la=i;
        }
    }
    else
    {
        int la=n-1;
        for(int i=n-2;i>=0;i--)
        {
            if(a[i].y<=a[la].y)
				del[i]=1;
            else
				la=i;
        }
    }
    int nn=0;
    for(int i=0;i<n;i++)
		if(!del[i])
			a[nn++]=a[i];
    return nn;
}
long long clc(int x,int y)
{
	return (b[y].x<a[x].x&&b[y].y<a[x].y)?0:1ll*(b[y].x-a[x].x)*(b[y].y-a[x].y);
}
long long wk(int l1,int r1,int l2,int r2)
{
	if(l1==r1)
		return 0;
	int mid=(l1+r1)>>1,w=l2;
	for(int i=l2+1;i<r2;i++)
		if(clc(mid,w)<clc(mid,i))
			w=i;
	return max(clc(mid,w),max(wk(l1,mid,l2,w+1),wk(mid+1,r1,w,r2)));
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        a[i].x=read(),a[i].y=read();
    for(int i=0;i<m;i++)
        b[i].x=read(),b[i].y=read();
    n=pre(a,n,0);
    m=pre(b,m,1);
    printf("%lld",wk(0,n,0,m));
	return 0;
}
posted @ 2018-04-24 19:49  lokiii  阅读(169)  评论(0编辑  收藏  举报