Codeforces Round #222 (Div. 1) D. Developing Game

D - Developing Game

思路:我们先枚举左边界,把合法的都扣出来,那么对于这些合法的来说值有v 和 r两维了,把v, r看成线段的两端,

问题就变成了,最多能选多少线段 使得不存在这样两条(l1 r1)  (l2 r2) l2 > r1,我们把线段l1 r1 看成二维平面内的点(l1, r1)

那么答案就变成了分别在(1, 1),  (2, 2),  (3, 3),  (4, 4), ....., (n, n)的左上的点的个数的最大值,我们用这个建

线段树然后就变成了区间加减问题。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 3e5 + 7;
const int M = 1e7 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;

int n;
struct segmentTree {
    int mx[N << 2], lazy[N << 2], id[N << 2];

    void pushdown(int rt) {
        if(lazy[rt]) {
            lazy[rt << 1] += lazy[rt];
            lazy[rt << 1 | 1] += lazy[rt];
            mx[rt << 1] += lazy[rt];
            mx[rt << 1 | 1] += lazy[rt];
            lazy[rt] = 0;
        }
    }

    void pushup(int rt) {
        if(mx[rt << 1] >= mx[rt << 1 | 1]) {
            mx[rt] = mx[rt << 1];
            id[rt] = id[rt << 1];
        } else {
            mx[rt] = mx[rt << 1 | 1];
            id[rt] = id[rt << 1 | 1];
        }
    }

    void build(int l, int r, int rt) {
        mx[rt] = lazy[rt] = 0;
        if(l == r) {
            id[rt] = l;
            return;
        }
        int mid = l + r >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }

    void update(int L, int R, int val, int l, int r, int rt) {
        if(l >= L && r <= R) {
            mx[rt] += val;
            lazy[rt] += val;
            return;
        }
        int mid = l + r >> 1;
        pushdown(rt);
        if(L <= mid) update(L, R, val, l, mid, rt << 1);
        if(R > mid) update(L, R, val, mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
} seg;

struct node {
    int l, v, r, id;
    bool operator < (const node &rhs) const {
        return l < rhs.l;
    }
} a[N];

int main() {
    seg.build(1, 300000, 1);
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d%d%d", &a[i].l, &a[i].v, &a[i].r), a[i].id = i;
    sort(a + 1, a + 1 + n);

    int ans = 0, ret1, ret2;
    priority_queue<PII, vector<PII>, greater<PII> > que;
    for(int i = 1, j = 1; i <= 300000; i++) {

        while(j <= n && a[j].l <= i) {
            int x = a[j].v, y = a[j].r;
            que.push(mk(x, y));
            seg.update(x, y, 1, 1, 300000, 1);
            j++;
        }

        while(!que.empty() && que.top() < mk(i, 0)) {
            PII now = que.top(); que.pop();
            seg.update(now.fi, now.se, -1, 1, 300000, 1);
        }

        if(ans < seg.mx[1]) {
            ans = seg.mx[1];
            ret1 = i;
            ret2 = seg.id[1];
        }
    }


    vector<int> vec;
    for(int i = 1; i <= n; i++) {
        if(a[i].l <= ret1 && a[i].v >= ret1 && a[i].v <= ret2 && a[i].r >= ret2)
            vec.push_back(a[i].id);
    }

    sort(vec.begin(), vec.end());
    printf("%d
", vec.size());
    for(int i = 0; i < vec.size(); i++)
        printf("%d ", vec[i]);
    puts("");
    return 0;
}


/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/9524950.html