• Codeforces Round #506 (Div. 3) C. Maximal Intersection


    C. Maximal Intersection
    time limit per test
    3 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given nn segments on a number line; each endpoint of every segment has integer coordinates. Some segments can degenerate to points. Segments can intersect with each other, be nested in each other or even coincide.

    The intersection of a sequence of segments is such a maximal set of points (not necesserily having integer coordinates) that each point lies within every segment from the sequence. If the resulting set isn't empty, then it always forms some continuous segment. The length of the intersection is the length of the resulting segment or 00 in case the intersection is an empty set.

    For example, the intersection of segments [1;5][1;5] and [3;10][3;10] is [3;5][3;5] (length 22), the intersection of segments [1;5][1;5] and [5;7][5;7] is [5;5][5;5](length 00) and the intersection of segments [1;5][1;5] and [6;6][6;6] is an empty set (length 00).

    Your task is to remove exactly one segment from the given sequence in such a way that the intersection of the remaining (n1)(n−1)segments has the maximal possible length.

    Input

    The first line contains a single integer nn (2n31052≤n≤3⋅105) — the number of segments in the sequence.

    Each of the next nn lines contains two integers lili and riri (0liri1090≤li≤ri≤109) — the description of the ii-th segment.

    Output

    Print a single integer — the maximal possible length of the intersection of (n1)(n−1) remaining segments after you remove exactly one segment from the sequence.

    Examples
    input
    Copy
    4
    1 3
    2 6
    0 4
    3 3
    output
    Copy
    1
    input
    Copy
    5
    2 6
    1 3
    0 4
    1 20
    0 4
    output
    Copy
    2
    input
    Copy
    3
    4 5
    1 2
    9 20
    output
    Copy
    0
    input
    Copy
    2
    3 10
    1 5
    output
    Copy
    7
    Note

    In the first example you should remove the segment [3;3][3;3], the intersection will become [2;3][2;3] (length 11). Removing any other segment will result in the intersection [3;3][3;3] (length 00).

    In the second example you should remove the segment [1;3][1;3] or segment [2;6][2;6], the intersection will become [2;4][2;4] (length 22) or [1;3][1;3](length 22), respectively. Removing any other segment will result in the intersection [2;3][2;3] (length 11).

    In the third example the intersection will become an empty set no matter the segment you remove.

    In the fourth example you will get the intersection [3;10][3;10] (length 77) if you remove the segment [1;5][1;5] or the intersection [1;5][1;5] (length 44) if you remove the segment [3;10][3;10].

    题意:给出n个区间,然后你可以删除一个区间,问你剩下的区间的交集的最大长度是多少

    思路:我们回到原始的求所有区间的交集,其实就是      距离左边最近的右边界-距离右边最近的左边界

    所以这个问题我们可以排个序,然后我们枚举要删除的边界,但是我们范围是10^5     n^2算法肯定不行,但我们又需要遍历,如果是nlogn的话肯定可以

    这个时候我们可以考虑set,内有自动排序的功能,也是由红黑树组成优化了时间复杂度,但是说可能会记录重复的,那我们就要使用 multiset,和set的区别就在于能记录重复

    然后我们枚举每个删除的区间即可

    #include <bits/stdc++.h>
    using namespace std;
    int l[300005], r[300005];
    multiset<int> a, b;
    int main(){
        int n;
        scanf("%d", &n);
        for(int i=1;i<=n;i++){
            scanf("%d%d", &l[i], &r[i]);
            a.insert(l[i]);
            b.insert(r[i]);
        }
        int ans = 0;
        for(int i=1;i<=n;i++){
            a.erase(a.find(l[i])); 
            b.erase(b.find(r[i]));
            ans = max(ans, *b.begin()-*a.rbegin());//取最大
            a.insert(l[i]);
            b.insert(r[i]);
        }
        printf("%d
    ", ans);
    }

     还有种 优先队列的写法更加快

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    int main() {
        int n,l[300010],r[300010];
        priority_queue<int> ml, mr;
        scanf("%d", &n);
        for (int i=0;i<n;++i) {
            scanf("%d %d", l+i, r+i);
            ml.push(l[i]);
            mr.push(-r[i]);
        }
        int ans = 0;
        bool bl, br;
        for (int i=0;i<n;++i) {
            bl = br = 0;
            if (ml.top()==l[i]) {
                bl = 1;
                ml.pop();
            }
            if (mr.top()==-r[i]) {
                br = 1;
                mr.pop();
            }
            ans = max(ans, -mr.top()-ml.top());
            if (bl) ml.push(l[i]);
            if (br) mr.push(-r[i]);
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    POJ1470 Closest Common Ancestors(LCA入门)
    POJ1330 Nearest Common Ancestors(倍增LCA算法求无边权树的模板)
    HDU3078 Network (倍增LCA算法求树链)
    HDU2874 Connections between cities(并查集+倍增LCA算法求森林最短路)
    HDU2586 How far away?(倍增LCA算法求带边权树上最短路)
    POJ1062 昂贵的聘礼
    HDU4725 The Shortest Path in Nya Graph(堆优化的dijkstra算法)
    数据仓库详解:包括概念、架构及设计
    利用行为标签构建用户画像
    Spark SQL深度理解篇:模块实现、代码结构及执行流程总览(2)
  • 原文地址:https://www.cnblogs.com/Lis-/p/9533030.html
Copyright © 2020-2023  润新知