Luogu 2082 区间覆盖(加强版)

版权声明:欢迎转载ヽ(•ω•ゞ)···如有表意不清或您没有看懂评论即可! https://blog.csdn.net/yandaoqiusheng/article/details/85012140

题目链接:传送门

题目描述

已知有N个区间,每个区间的范围是[si,ti],请求出区间覆盖后的总长。

输入格式:

N s1 t1 s2 t2 …… sn tn

输出格式:

共一行,一个正整数,为覆盖后的区间总长。

输入样例

3
1 100000
200001 1000000
100000000 100000001

输出样例

900002

说明

【数据范围】
对于40%的数据 N 1000 0 < S i < T i 10000 N≤1000,0<Si<Ti≤10000
对于100%的数据 N 1 0 5 0 < S i < T i 1 0 17 N≤10^5,0<Si<Ti≤10^{17} ,且为整数

珂朵莉树基本应用题
区间询问就够了
虽然这是道贪心,

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define A 1000010
#define B 2010

using namespace std;
typedef long long ll;
struct node {
    ll l, r;
    mutable ll v;
    node (ll L = 0, ll R = -1, ll V = 0) : l(L), r(R), v(V) {}
    bool operator < (const node &a)const {
        return l < a.l;
    }
};
set<node> s;
int n;
ll l, r;
#define iter set<node>::iterator
iter split(ll pos) {
    iter it = s.lower_bound(node(pos));
    if (it != s.end() and it->l == pos) return it;
    --it;
    ll l = it->l, r = it->r, val = it->v;
    s.erase(it);
    s.insert(node(l, pos - 1, val));
    return s.insert(node(pos, r, val)).first;
}
void assign(ll l, ll r) {
    iter rrc = split(r + 1), llc = split(l);
    s.erase(llc, rrc);
    s.insert(node(l, r, 1LL));
}
ll ask(ll l, ll r) {
    iter llc = split(l), rrc = split(r + 1);
    ll ans = 0;
    for (; llc != rrc; llc++)
      if (llc->v) //覆盖掉的就加上
        ans += llc->r - llc->l + 1;
    return ans;
}

int main() {
    scanf("%d", &n);
    s.insert(node(0, ll(1e17 + 2), 0)); //初始节点
    for (int i = 1; i <= n; i++) {
        scanf("%lld%lld", &l, &r);
        assign(l, r);
    }
    printf("%lld\n", ask(0, 1e17));
}

猜你喜欢

转载自blog.csdn.net/yandaoqiusheng/article/details/85012140