线段相交的异或值 (线段树 or 优先队列)
VVQ 最近迷上了线段这种东西
现在他手上有 n 条线段,他希望在其中找到两条有公共点的线段,使得他们的异或值最大。 定义线段的异或值为它们并的长度减他们交的长度
输入描述:
第一行包括一个正整数 n,表示 VVQ 拥有的线段条数。
接下来 n 行每行包括两个正整数 l,r,表示 VVQ 拥有的线段的 左右端点。
输出描述:
一行一个整数,表示能得到的最大异或值
输入
3
10 100
1 50
50 100
输出
99
说明
选择第二条和第三条,99-0=99
备注:
1<=n<=200000,1<=l<=r<=1e8 题意 : 在坐标轴上面有很多线段,问你所有有公共点的线段的异或值最大是多少?
思路 : 所以线段只有 3 种情况, 1 是不相交, 2是相交, 3是包含,第一种情况的答案是 0, 对于第二种情况 假设2条线段i,j,且靠右的线段是 j,则此情况下的异或值是
rj+lj-(ri+li),将 i 看成是不变的量,让 j线段的值最大即可,线段树维护就可以了, 对于第三种情况,答案是 (rj-lj)-(ri-li),则此时值需要让 ri-rl的值最小即可。
代码示例 :
#define ll long long
const int maxn = 2e5+5;
const int mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
#define lson k<<1
#define rson k<<1|1 struct edge
{
int l, r;
bool operator< (const edge &v)const{
return l < v.l;
}
}pre[maxn]; struct node
{
int l, r;
int mi,ma;
}t[maxn<<2]; void pushup(int k){
t[k].ma = max(t[lson].ma, t[rson].ma);
t[k].mi = min(t[lson].mi, t[rson].mi);
} void build(int l, int r, int k){
t[k].l = l;
t[k].r = r;
if (l == r){
t[k].ma = pre[l].l+pre[l].r;
t[k].mi = pre[l].r-pre[l].l;
return;
}
int mid = (l+r) >> 1;
build(l, mid, lson);
build(mid+1, r, rson);
pushup(k);
}
int sum = 0;
void query(int l, int r, int k){
if (l <= t[k].l && t[k].r <= r){
sum = max(sum, t[k].ma);
return;
}
int m = (t[k].l+t[k].r)>>1;
if (l <= m) query(l, r, lson);
if (r > m) query(l, r, rson);
} void query2(int l, int r, int k){
if (l <= t[k].l && t[k].r <= r){
sum = min(sum, t[k].mi);
return;
}
int m = (t[k].l+t[k].r)>>1;
if (l <= m) query2(l, r, lson);
if (r > m) query2(l, r, rson);
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int n; cin >>n;
for(int i = 1; i <= n; i++){
scanf("%d%d", &pre[i].l, &pre[i].r);
}
sort(pre+1, pre+1+n);
build(1, n, 1);
int ans = 0;
edge tem;
for(int i = 1; i <= n; i++){
tem.l = pre[i].l;
int p1 = lower_bound(pre+1, pre+1+n, tem)-pre;
tem.l = pre[i].r;
int p2 = upper_bound(pre+1, pre+1+n, tem)-pre-1;
sum = 0;
//printf("p1 = %d p2 = %d\n", p1, p2);
query(p1, p2, 1);
ans = max(ans, sum-(pre[i].l+pre[i].r));
sum = inf;
query2(p1, p2, 1);
ans = max(ans, pre[i].r-pre[i].l-sum);
}
printf("%d\n", ans);
return 0;
}
方法二 : 优先队列(自己的超时了,先借鉴一个,待更新)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
int n, m; struct P {
int l, r;
bool operator < (const P &t) const {
return l + r > t.l + t.r;
}
} p[maxn]; bool cmp(P a, P b) {
return a.l == b.l ? a.r < b.r : a.l < b.l;
} int main() {
while(~scanf("%d", &n)) {
for(int i = 0; i < n; i++) scanf("%d %d", &p[i].l, &p[i].r);
sort(p, p + n, cmp);
priority_queue<P> q;
priority_queue<P> Q;
q.push(p[0]);
Q.push({p[0].l, -p[0].r});
int ans = 0;
for(int i = 1; i < n; i++) {
while(!Q.empty() && -Q.top().r < p[i].l) Q.pop();
if(!Q.empty() && -Q.top().r > p[i].r) ans = max(ans, -(Q.top().r + Q.top().l) - p[i].r + p[i].l);
Q.push({p[i].l, -p[i].r});
while(!q.empty() && q.top().r < p[i].l) q.pop();
//p中所有点已按l排序,当前点与队列里第一个点不相交,后面的点一定不相交
if(!q.empty()) ans = max(ans, p[i].l + p[i].r - q.top().l- q.top().r);
q.push(p[i]);
}
printf("%d\n", ans);
}
return 0;
}
线段相交的异或值 (线段树 or 优先队列)的更多相关文章
- 【计算几何初步-线段相交】【HDU1089】线段交点
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- 判断直线与线段相交 POJ 3304 Segments
题意:在二维平面中,给定一些线段,然后判断在某直线上的投影是否有公共点. 转化,既然是投影,那么就是求是否存在一条直线L和所有的线段都相交. 证明: 下面给出具体的分析:先考虑一个特殊的情况,即n=1 ...
- hdu 1086(判断线段相交)
传送门:You can Solve a Geometry Problem too 题意:给n条线段,判断相交的点数. 分析:判断线段相交模板题,快速排斥实验原理就是每条线段代表的向量和该线段的一个端点 ...
- poj 3304 判断是否存在一条直线与所有线段相交
Segments Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8579 Accepted: 2608 Descript ...
- BZOJ 4777 Usaco2017 Open Switch Grass Kruskal+替罪羊树+权值线段树
这道题首先可以看出答案一定是一条边,而且答案一定在最小生成树上,那么我们就可以在这个最小生成树上维护他与异色儿子的边最小值,所以我们就可以已通过Kruskal和一棵平衡树来解决,时间复杂度是O(n*l ...
- 【bzoj3065】带插入区间K小值 替罪羊树套权值线段树
题目描述 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它的随从伏特提出 ...
- 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树
[BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...
- 【BZOJ4605】崂山白花蛇草水 权值线段树+kd-tree
[BZOJ4605]崂山白花蛇草水 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了 ...
- 【bzoj4605】崂山白花蛇草水 权值线段树套KD-tree
题目描述 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了山东省省队,现在便是他履行诺言的时候了.蒟蒻Bob ...
随机推荐
- H3C 单区域OSPF配置示例一(续)
- python基础九之函数
1,函数的定义 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数分为自定义函数和内置函数,内置函数就是python内部自带的一些函数,如:print().int()等.自定义函数 ...
- H3C H3C设备DNS功能实现
- vue-learning:11 -js-nextTick()
nextTick() 在jQuery中,如果我们要生成一个ul-li的列表元素,我们也不会在循环体中每生成一个li就将它插入到ul中,而是在循环体内拼接每个li,待循环体结束后,再一并添加到ul元素上 ...
- 两种常见的缓存淘汰算法LFU&LRU
1. LFU 1.1. 原理 LFU(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”. 1.2. ...
- Build 2017(简体中文视频)
视频汇总地址 入口 可筛选某天的视频 部分包含中文字幕 我看过的视频 Day1 #MSBuild Day 1 Keynote(中文字幕) Three Runtimes, one standard… . ...
- Visio主题与样式
o visio内置了27种主题样式 共有四个分类 每个主题样式都有四个变体可供选择 重复就是复制的意思 就是复制页面 可以设置将某一个主题应用于当前页或者所有页 所有页面指的是所有有相同背景的页面 允 ...
- 基于 HTML5 + WebGL 的无人机 3D 可视化系统
前言 近年来,无人机的发展越发迅速,既可民用于航拍,又可军用于侦察,涉及行业广泛,也被称为“会飞的照相机”.但作为军事使用,无人机的各项性能要求更加严格.重要.本系统则是通过 Hightopo 的 ...
- pyinstaller打包exe文件闪退的解决办法
pyinstaller是python下目前能打包py文件为windows下的exe文件的一个非常友好易用的库!但是,小爬每次用pyinstaller打包时也总是遇到一些难题,有时网上搜了一圈,也没看到 ...
- python tkinter动态追加按钮等控件可能遇到的问题
小爬最近给同事制作一个小爬虫:具体要求: 1.每天自动定时触发: 2.模拟用户自动登陆: 3.自动爬取对应API接口数据: 4.对爬取结果进行逻辑判断,对符合条件的数据进行规则化列示: 5.列示的行项 ...