链接:https://codeforces.com/problemset/problem/1285/E

题意:给一个数轴上有n个线段集,线段集若有相交,则合并为一个新的合并线段集,比如[1,6]和[2,9],因为两个线段有相交,所以要合并为[1,9],先问删掉给定的n个线段集中的任意一个,剩下的n-1个线段组成的新的合并线段集数量最大是多少?

思路:

这道题首先想到的是并查集做法,枚举删除任意一条线段后,剩下的线段组成的集合是多少,取max,这个复杂度有n2 × 并查集复杂度,显然是不行的。那么考虑离散化处理线段左右端点,然后去扫描。

如图所示,线段1,2,3,4离散化处理左右端点,然后排个序并标记一下线段号,开始扫描,扫描到的端点先放入multiset集合中去,最初扫描到线段1的左端点L1,然后是L2,再然后是R1,此时我们发现,线段1已经扫描完比,那么删除这条线段1的左右端点,发现集合中只剩下了L2,且下一个要扫描到的端点是L3,此时就意味着删除点线段2后,线段1和线段3是不相交的,那么删除线段2后,新线段合并集合数量就会+1。同理当扫描到R2时,整个线段2已经扫描完毕,删除集合中线段2左右端点,集合只剩下线段3的左端点,且下一个元素是线段4的左端点,说明线段2和线段4不相交,那么此时删除线段3,就意味着线段2和线段4不相连,新线段合并集合数量就+1,根据以上这个性质,扫描的时候枚举下个元素是左端点还是右端点,记录删除每个线段删除后,合并集合会增加多少,最终拿最初不删除任何线段得到的合并线段集数量+max(删除某一线段增加的数量)就是答案

当然要特判一种情况:

如图所示线段1这种情况,删除这条线段,则新合并集是-1,因为它没有和任何线段有相交,本身就构成一个独立的合并线段集,删除就减少1个合并线段集,特判这种情况即可。

AC代码:

 #include<iostream>
#include<vector>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 4e5+;
pair<ll,ll> p[maxn];
int cnt[maxn];
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i = ;i<=n;i++){
ll l,r;
cin>>l>>r;
p[*i-] = make_pair(l,-i);//离散化记录区间左右端点的位置和区间标号i
p[*i] = make_pair(r,i);
cnt[i] = ;
}
sort(p+,p+*n+);
int ans = ;
multiset<int> s;
for(int i = ;i<=*n;i++){
if(p[i].second < ){//如果是左端点,就插入set
s.insert(-p[i].second );
}
else{
s.erase(s.find(p[i].second));//如果是右端点,就把这个区间删除
}
if(s.size() == ) ans++;//如果集合是空,记录一个合并的区间
if(s.size() == && p[i].second > && p[i+].second < && p[i+].first > p[i].first ){
cnt[*s.begin()]++;//当前是左端点,但是下个是右端点,cnt++
}
if(s.size() == && p[i].second < && p[i+].second >){
cnt[*s.begin()]--;//如果首先插入地是一段单独区间(l r),去掉这个区间则区间数量-1
}
}
int t = -;
for(int i = ;i<=n;i++){
t = max(t,cnt[i]);
}
cout<<ans+t<<endl;
}
return ;
}

codeforces 1285E. Delete a Segment的更多相关文章

  1. Educational Codeforces Round 53 E. Segment Sum(数位DP)

    Educational Codeforces Round 53 E. Segment Sum 题意: 问[L,R]区间内有多少个数满足:其由不超过k种数字构成. 思路: 数位DP裸题,也比较好想.由于 ...

  2. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  3. codeforces B. The Fibonacci Segment 解题报告

    题目链接:http://codeforces.com/problemset/problem/365/B 题目意思:简单来说,就是要找出最长的斐波纳契长度. 解决的方法不难,但是要注意更新左区间和右区间 ...

  4. codeforces 242E - XOR on Segment (线段树 按位数建树)

    E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...

  5. E. Delete a Segment(删除一个区间,让并区间最多)

    题:https://codeforces.com/contest/1285/problem/E 题意:给定n个区间,最多删除一个区间,让最后的并区间个数最大 #include<bits/stdc ...

  6. CodeForces 242E - XOR on Segment 二维线段树?

    今天练习赛的题....又是线段树的变换..拿到题我就敲了个点更新区间查询的..果断超时...然后想到了可以将每个数与合表示成不进位的二进制数..这样就可以区间进行更新了..比赛的时候写搓了..刚重写了 ...

  7. codeforces 242E. XOR on Segment 线段树

    题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...

  8. CodeForces 616D Longest k-Good Segment

    用队列维护一下即可 #include<cstdio> #include<cstring> #include<queue> #include<algorithm ...

  9. CodeForces 730H Delete Them (暴力)

    题意:给定n个名字,然后让你删除 m 个,且这m个必须满足同一个表达式且其他的不满足,问你能不能找到一个满足条件. 析:很明显首先知道的是这 m 个如果第 i 个位置相同,那么就肯定选这个位置是最好的 ...

随机推荐

  1. 论文阅读笔记(二十一)【CVPR2017】:Deep Spatial-Temporal Fusion Network for Video-Based Person Re-Identification

    Introduction (1)Motivation: 当前CNN无法提取图像序列的关系特征:RNN较为忽视视频序列前期的帧信息,也缺乏对于步态等具体信息的提取:Siamese损失和Triplet损失 ...

  2. Java使用POI读取Word中的表格

    个人博客 地址:https://www.wenhaofan.com/a/20190627135921 代码 package live.autu.word; import java.io.FileInp ...

  3. 卸载Windows控制面板的程序和功能中找不到的一些软件的方法

    卸载Windows控制面板的程序和功能中找不到的一些软件的方法 找到卸载程序进行卸载即可

  4. Java设计模式(一)UML总结

    定义 统一建模语言(英语: Unified Modeling Language ,缩写UML)是非专利的第三代建模和规约语言. UML特点 UML是一种开放的方法 用于说明.可视化.构建和编写一个正在 ...

  5. mybatis-plus invalid bound statement (not found) insert解决办法

    使用mybatis-plus时,使用IService.insert方法时,提示找不到insert方法,原因是,mybatis-plus提供了两个BaseMapper和IService. 改成引用imp ...

  6. opencv图像加文字与运行时间

    //获取推断时间 vector<double>layterTimings; double freq = getTickFrequency() / 1000; //得到ms double t ...

  7. 【Python】求n!

    阶乘是基斯顿·卡曼(Christian Kramp,1760-1826)于1808年发明的运算符号,是数学术语.一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1 ...

  8. redis看这一篇就够了

    redis的下载安装 准备相关依赖 yum install gcc 下载安装包 # 切换到存放安装包到目录 cd /usr/local # 下载安装包 wget http://download.red ...

  9. smarty循环item命名规范

    使用smarty循环渲染数据时第二次循环item复制命名不规范 item=data 后面代码使用data会与后台返回数据冲突 {%foreach from=$data.bind_data key=ke ...

  10. 使用word时在方块中打钩

    ☑ 方法一: 第一步: 输入:2611 第二步: 选中2611 第三步: 按Alt + X Get :  ☑ 同样:用2610代替2611会得到☐ ☐2610 ☑2611 方法二 1.选择[插入]-- ...