时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制: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;
}