排序 + 二分 - The Treasure of The Segments - CF 690 F

排序 + 二分 - The Treasure of The Segments - CF 690 F

题意:

给 定 n 个 区 间 , 给定n个区间, n

现 在 从 中 删 除 一 些 区 间 , 使 得 这 n 个 区 间 中 至 少 存 在 一 个 区 间 , 现在从中删除一些区间,使得这n个区间中至少存在一个区间, 使n

满 足 这 个 区 间 和 其 他 所 有 的 区 间 都 相 交 。 满足这个区间和其他所有的区间都相交。

计 算 最 少 删 除 多 少 个 区 间 , 能 够 满 足 条 件 。 计算最少删除多少个区间,能够满足条件。

输入:

首 行 一 个 正 整 数 T , 表 示 测 试 数 据 个 数 , 首行一个正整数T,表示测试数据个数, T

每 组 数 据 首 行 一 个 正 整 数 n , 表 示 区 间 数 量 , 每组数据首行一个正整数n,表示区间数量, n

接 着 n 行 , 每 行 两 个 正 整 数 , 表 示 区 间 的 左 右 端 点 l i , r i 。 接着n行,每行两个正整数,表示区间的左右端点l_i,r_i。 nli,ri

输出:

一 个 正 整 数 , 表 示 答 案 。 一个正整数,表示答案。

Example
input

4
3
1 4
2 3
3 6
4
1 2
2 3
3 5
4 5
5
1 2
3 8
4 5
6 7
9 10
5
1 5
2 4
3 5
3 8
4 8

output

0
1
2
0

数据范围:

数 据 保 证 ∑ n ≤ 2 ⋅ 1 0 5 , 1 ≤ l ≤ r ≤ 1 0 9 数据保证\sum n\le 2·10^5,1\le l\le r\le 10^9 n21051lr109


分析:

最 初 的 想 法 是 : 对 每 个 区 间 , 统 计 和 这 个 区 间 相 交 的 区 间 数 , n − 最 大 值 就 是 答 案 。 最初的想法是:对每个区间,统计和这个区间相交的区间数,n-最大值就是答案。 n

问 题 在 于 , 很 难 在 n l o g n 的 时 间 复 杂 度 内 统 计 出 和 每 个 区 间 相 交 的 区 间 数 。 问题在于,很难在nlogn的时间复杂度内统计出和每个区间相交的区间数。 nlogn

所 以 , 我 们 反 过 来 思 考 , 对 每 个 区 间 , 统 计 和 该 区 间 不 相 交 的 区 间 数 , 那 么 最 小 值 就 是 答 案 。 所以,我们反过来思考,对每个区间,统计和该区间不相交的区间数,那么最小值就是答案。

而 与 每 个 区 间 不 相 交 的 区 间 数 是 好 统 计 的 , 因 为 , 和 区 间 [ l i , r i ] 和 [ l 0 , r 0 ] 不 相 交 , 只 有 两 种 情 况 : 而与每个区间不相交的区间数是好统计的,因为,和区间[l_i,r_i]和[l_0,r_0]不相交,只有两种情况: [li,ri][l0,r0]

① 、 r 0 < l i ①、r_0<l_i r0<li

② 、 l 0 > r i ②、l_0>r_i l0>ri

首 先 , 我 们 对 区 间 的 左 端 点 和 右 端 点 分 别 排 序 , 首先,我们对区间的左端点和右端点分别排序,

然 后 ,   对 于 每 个 区 间 [ l i , r i ] , 我 们 二 分 第 一 个 > r i 的 左 端 点 的 位 置 p o s 1 , 它 的 贡 献 是 n − p o s 1 + 1 然后,\\ \ \\对于每个区间[l_i,r_i],我们二分第一个>r_i的左端点的位置pos_1,它的贡献是n-pos_1+1  [li,ri]>ripos1npos1+1

我 们 再 二 分 第 一 个 ≥ l i 的 右 端 点 的 位 置 p o s 2 , 它 的 贡 献 是 p o s 2 − 1 。 我们再二分第一个\ge l_i的右端点的位置pos_2,它的贡献是pos_2-1。 lipos2pos21

最 后 我 们 更 新 最 小 值 m i n 1 ≤ i ≤ n ( n − p o s 1 + 1 , p o s 2 − 1 ) , 即 答 案 。 最后我们更新最小值min_{1\le i\le n}(n-pos_1+1,pos_2-1),即答案。 min1in(npos1+1,pos21)

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>

#define P pair<int,int>
#define l first
#define r second

using namespace std;

const int N = 200010;

int n, T;
P s1[N], s2[N];
int l[N], r[N];

int main()
{
    ios::sync_with_stdio(false);
    
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) 
        {
            int l, r;
            cin>>l>>r;
            s1[i]={l,r}, s2[i]={r,l};
        }
        sort(s1+1,s1+n+1);
        sort(s2+1,s2+n+1);
        for(int i=1;i<=n;i++) 
            l[i] = s1[i].l, 
            r[i] = s2[i].l;
            
        int ans = n;
        for(int i=1;i<=n;i++)
        {
            int tmp = 0;
            int pos = upper_bound(l+1,l+n+1,s1[i].r) - l;
            tmp += n - pos + 1;
            pos = lower_bound(r+1,r+n+1,s1[i].l) - r;
            tmp += pos - 1;
            ans = min(ans, tmp);
        }
        
        cout<<ans<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值