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;
}

 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值