Codeforces Round #506 (Div. 3) C. Maximal Intersection (线段树)

题目链接:http://codeforces.com/contest/1029/problem/C

题目大意:给出n条线段,第 i 条线段的左端点为 li ,右端点为 ri。现在你可以将这n条线段中的一条删去,问你要删去哪条线段才能使被剩下的n-1条线段所覆盖的区域尽可能的长。

题目思路:线段覆盖的话,我们可以考虑用线段树来维护,由于本题的 li 和 ri 都可以达到1e9,所以我们要先离散化一下,再用线段树维护。线段树中维护的是一段区间内被线段覆盖的最大次数。接着就可以枚举删掉哪条线段,每次先将这条线段从线段树中删去,再找到线段树内值为n-1的区间,由于线段树内维护的是最大值,所以我们可以用一个查询函数queryl来查询被n-1条线段覆盖的区间的左端点,用queryr来查询被n-1条线段覆盖的区间的右端点。查询的时候只需要根据情况选择往左子树查询,或者往右子树查询即可。复杂度为O(n*logn)。

具体实现看代码:

#include <bits/stdc++.h>
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pb push_back
#define MP make_pair
#define lowbit(x) x&-x
#define clr(a) memset(a,0,sizeof(a))
#define _INF(a) memset(a,0x3f,sizeof(a))
#define FIN freopen("in.txt","r",stdin)
#define IOS ios::sync_with_stdio(false)
#define fuck(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>pll;
typedef pair<int, int>pii;
typedef vector<int> VI;
const int inf = 0x3f3f3f3f;
const int MX = 1e6 + 7;

int n;
struct node {
    int l, r;
} a[MX];
VI h;
int get_id(int x) {
    return lower_bound(h.begin(), h.end(), x) - h.begin() + 1;
}
int MAX[MX << 2], tag[MX << 2];
void push_up(int rt) {
    MAX[rt] = max(MAX[rt << 1], MAX[rt << 1 | 1]);
}
void push_down(int rt) {
    if (tag[rt] != 0) {
        MAX[rt << 1] += tag[rt];
        MAX[rt << 1 | 1] += tag[rt];

        tag[rt << 1] += tag[rt];
        tag[rt << 1 | 1] += tag[rt];

        tag[rt] = 0;
    }
}
void update(int L, int R, int d, int l, int r, int rt) {
    if (L <= l && r <= R) {
        tag[rt] += d;
        MAX[rt] += d;
        return;
    }
    push_down(rt);
    int m = (l + r) >> 1;
    if (L <= m) update(L, R, d, lson);
    if (R > m) update(L, R, d, rson);
    push_up(rt);
}

int queryl(int d, int l, int r, int rt) {
    if (l == r) return l;
    push_down(rt);
    int m = (l + r) >> 1;
    if (MAX[rt << 1] >= d) return queryl(d, lson);
    else return queryl(d, rson);
}
int queryr(int d, int l, int r, int rt) {
    if (l == r) return l;
    push_down(rt);
    int m = (l + r) >> 1;
    if (MAX[rt << 1 | 1] >= d) return queryr(d, rson);
    else return queryr(d, lson);
}

int main() {
    //FIN;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].l, &a[i].r);
        h.pb(a[i].l); h.pb(a[i].r);
    }
    sort(h.begin(), h.end());
    h.erase(unique(h.begin(), h.end()), h.end());
    int N = n << 1;
    for (int i = 1; i <= n; i++) {
        int l = get_id(a[i].l), r = get_id(a[i].r);
        update(l, r, 1, 1, N, 1);
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        int l = get_id(a[i].l), r = get_id(a[i].r);
        update(l, r, -1, 1, N, 1);
        if (MAX[1] >= n - 1) {
            int L = queryl(n - 1, 1, N, 1), R = queryr(n - 1, 1, N, 1);
            L = h[L - 1], R = h[R - 1];
            ans = max(ans, R - L);
        }
        update(l, r, 1, 1, N, 1);
    }
    printf("%d\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Lee_w_j__/article/details/82502856
今日推荐