Luogu AT2557 【Ball Coloring】

题目大意:

有n对数字,让你将这n对数字染色成红的或蓝的,求\((Rmax-Rmin)*(Bmax-Bmin)\)
\(n<=2e5,0<a<=1e9\)

解题过程:

还是luogu比较香.....
在atcode上不会做今天用luogu看就会了是什么鬼...
(难道我的水平和OJ界面成正比???)
首先这里只有两组而且显然是计算答案的时候是对称的两组
所以考虑让最大值出现在R里面,那么最小值就有两种情况

  • 最小值出现在B里面
    那就很easy了,让\(Rmin\)最大,\(Bmax\)最小即可,直接
    大的丢到\(a\)里小的丢到\(b\)里就行
  • 最小值出现在\(R\)里面
    这个比较烦,但是手玩一下样例还是可以搞的
    我们现在是想让\(Bmax\)最小,\(Bmin\)最大就行
    那么就先满足\(Bmax\)最小这个条件,按每一组
    的最小值排序,先把小的丢给B,大的丢给R,然后
    从前到后枚举每一个数对,把它翻过去,然后更新答案就行
    那么为啥可以这样咧?
    因为我们从前到后翻的时候最小值在不断变
    大,如果我们把前面的一个翻回来,那么最小值就会变小,而最大值
    并不会变化,那么答案就变大了,舍弃。如果强行把最大值调小
    那么你会发现这种情况之前已经枚举过了,不用考虑
    综上所述,我们枚举一遍,同时维护最大最小值就可以了
    直接开线段树就行,\(2e5\)丝毫不慌的.
    (我去,线段树跑这么快????)
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;

#define R register
#define ll long long

const ll inf=(1LL<<60);
const int MAXN=2e5+10;

int n;
struct Pair
{
	int x,y;
}p[MAXN];

ll ans=inf;
int a[MAXN],b[MAXN];

inline void solve1()
{
	for(R int i=1;i<=n;i++)
	a[i]=p[i].x,b[i]=p[i].y;
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	ll res=(ll)(a[n]-a[1])*(b[n]-b[1]);
	if(res<ans) ans=res;
}

struct Segment_Tree
{
	int mx[MAXN<<2],mn[MAXN<<2];
	inline int ls(int x) { return x<<1; }
	inline int rs(int x) { return x<<1|1; }
	inline void update(int x)
	{
		mx[x]=max(mx[ls(x)],mx[rs(x)]);
		mn[x]=min(mn[ls(x)],mn[rs(x)]);
	}
	inline void chg(int x,int l,int r,int ad,int k)
	{
		if(l==r)
		{
			mn[x]=mx[x]=k;
			return;
		}
		int mid=l+r;mid>>=1;
		if(ad<=mid) chg(ls(x),l,mid,ad,k);
		else chg(rs(x),mid+1,r,ad,k);
		update(x);
	}
	inline int findmin()
	{
		return mn[1];
	}
	inline int findmax()
	{
		return mx[1];
	}
}Tr,Tb;

inline bool cmp(Pair p1,Pair p2)
{
	if(p1.x==p2.x) return p1.y<p2.y;
	return p1.x<p2.x;
}

int tag[MAXN];

inline void solve2()
{
	sort(p+1,p+1+n,cmp);
	int mxnode=-1,mxnum1=-1,mxnum2=-1;
	for(R int i=1;i<=n;i++)
	{
		if(p[i].y>mxnum1)
		{
			mxnode=i;
			mxnum1=p[i].y;
			mxnum2=p[i].x;
			continue;
		}
		if(p[i].y==mxnum1)
		{
			if(p[i].x>mxnum2)
			{
				mxnode=i;
				mxnum2=p[i].x;
				continue;
			}
		}
	}
	tag[mxnode]=1;
	swap(p[1].x,p[1].y);
	tag[1]=1;
	for(R int i=1;i<=n;i++)
	{
		Tb.chg(1,1,n,i,p[i].x);
		Tr.chg(1,1,n,i,p[i].y);
	}
	ll res=(ll)(Tb.findmax()-Tb.findmin())*(Tr.findmax()-Tr.findmin());
	if(res<ans) ans=res;
	for(R int i=1;i<=n;i++)
	{
		if(tag[i]) continue;
		Tb.chg(1,1,n,i,p[i].y);
		Tr.chg(1,1,n,i,p[i].x);
		ll tres=(ll)(Tb.findmax()-Tb.findmin())*(Tr.findmax()-Tr.findmin());
		if(tres<ans) ans=tres;
	}
}

int main()
{
	scanf("%d",&n);
	for(R int i=1;i<=n;i++)
	{
		int x,y;scanf("%d%d",&x,&y);
		if(x>y) swap(x,y);
		p[i].x=x;
		p[i].y=y;
	}
	solve1();
	solve2();
	printf("%lld\n",ans);
	return 0;
}
posted @ 2020-04-30 17:37  HN-wrp  阅读(104)  评论(0编辑  收藏  举报