布呗之路

跑不出的nlogn

Wannafly挑战赛13 E VVQ 与线段

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

VVQ 最近迷上了线段这种东西

现在他手上有 n 条线段,他希望在其中找到两条有公共点的线段,使得他们的异或值最大。 定义线段的异或值为它们并的长度减他们交的长度


输入描述:

第一行包括一个正整数 n,表示 VVQ 拥有的线段条数。
接下来 n 行每行包括两个正整数 l,r,表示 VVQ 拥有的线段的 左右端点。

输出描述:

一行一个整数,表示能得到的最大异或值
示例1

输入

3 
10 100 
1 50 
50 100

输出

99

说明

选择第二条和第三条,99-0=99

备注:

1<=n<=200000,1<=l<=r<=1e8
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;

const int maxn=1e6+7;
pair<int,int> a[maxn];

/**

将线段端点存入pair,利用其自带排序函数对位置进行排序;
因此,只需讨论相交和包含两种情况(相离舍去);

线段a内部包含线段b 贡献:(a.r-a.l)-(b.r-b.l);
线段a与线段b相交   贡献:(a.r+b.l-b.l-b.r);

Q1: 包含贡献(大);
Q2: 相交贡献(小);
优先队列当前状态与右边(a[i])当前状态信息进行暴力模拟;
*/
struct node1{
	int l,r;
	node1(int x,int y){l=x;r=y;}
	friend bool operator <(node1 a,node1 b){return (a.r-a.l)<(b.r-b.l);}
};
struct node2{
	int l,r;
	node2(int a,int b){l=a;r=b;}
	friend bool operator <(node2 a,node2 b){return a.l+a.r>b.l+b.r;}
};
/**
bool operator <()(node1 a,node1 b){return a.r-a.l<b.r-b.l;}
bool operator <()(node2 a,node2 b){return a.l+a.r>b.l+b.r;}
*/

int main (){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d %d",&a[i].fi,&a[i].se);
	sort(a,a+n);
	priority_queue <node1>Q1;
	priority_queue <node2>Q2;
	Q1.push(node1(a[0].fi,a[0].se));
	Q2.push(node2(a[0].fi,a[0].se));
	int ans=0;
	for(int i=1;i<n;i++){
		while(!Q1.empty()&&Q1.top().r<a[i].se) Q1.pop();
		while(!Q2.empty()&&Q2.top().r<a[i].fi) Q2.pop();
		if(!Q1.empty()) ans=max(ans,Q1.top().r-Q1.top().l-a[i].se+a[i].fi);
		if(!Q2.empty()) ans=max(ans,a[i].fi+a[i].se-Q2.top().l-Q2.top().r);
		Q1.push(node1(a[i].fi,a[i].se));
		Q2.push(node2(a[i].fi,a[i].se));
  	}
  	cout<<ans<<endl;
	return 0;
}

阅读更多
版权声明:布呗之路的守望者 https://blog.csdn.net/hypHuangYanPing/article/details/79980909
个人分类: 牛客网系列赛
上一篇Hrbust 2373 小C的问题
下一篇Wannafly挑战赛13 D applese的生日
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭