Luogu AT2557 【Ball Coloring】

題目大意:

有n對數字,讓你將這n對數字染色成紅的或藍的,求
\((Rmax-Rmin)*(Bmax-Bmin)\)
\(n<=2e5,0<a<=1e9\)node

解題過程:

仍是luogu比較香.....
在atcode上不會作今天用luogu看就會了是什麼鬼...
(難道個人水平和OJ界面成正比???)
首先這裏只有兩組並且顯然是計算答案的時候是對稱的兩組
因此考慮讓最大值出如今R裏面,那麼最小值就有兩種狀況ios

  • 最小值出如今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;
}
相關文章
相關標籤/搜索