[传送门]

将第二维离散化一下,按第一维从大到小,第二维从,第三维从大到小排序,这样即使第一维相同的情况下也不会重,然后用一棵线段树维护第二维为$I_{i}$时第三维的最大值,插入每一个元素之前先查询$\left[I_{i} + 1, n\right]$的最大值,若查询得到的$x$大于$R_{i}$,$ans++$

#include <bits/stdc++.h>
using namespace std;

const int N = 5e5 + 7;

struct P {
    int f, s, t;
    inline bool operator < (const P &rhs) const {
        if (rhs.f == f && rhs.s == s) return t > rhs.t;
        if (f == rhs.f) return s < rhs.s;
        return f > rhs.f;
    }
} p[N];

int n, v[N];

struct Seg {
    #define lp p << 1
    #define rp p << 1 | 1
    int tree[N << 2];
    inline void pushup(int p) {
        tree[p] = max(tree[lp], tree[rp]);
    }
    void update(int p, int l, int r, int pos, int val) {
        if (l == r) {
            tree[p] = max(tree[p], val);
            return;
        }
        int mid = l + r >> 1;
        if (pos <= mid) update(lp, l, mid, pos, val);
        else update(rp, mid + 1, r, pos, val);
        pushup(p);
    }
    int query(int p, int l, int r, int x, int y) {
        if (x <= l && y >= r) return tree[p];
        int mid = l + r >> 1;
        int ans = 0;
        if (x <= mid) ans = max(ans, query(lp, l, mid, x, y));
        if (y > mid) ans = max(ans, query(rp, mid + 1, r, x, y));
        return ans;
    }
} seg;

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &p[i].f);
    for (int i = 1; i <= n; i++)
        scanf("%d", &p[i].s), v[i] = p[i].s;
    for (int i = 1; i <= n; i++)
        scanf("%d", &p[i].t);
    sort(v + 1, v + 1 + n);
    int cnt = unique(v + 1, v + 1 + n) - v - 1;
    for (int i = 1; i <= n; i++)
        p[i].s = lower_bound(v + 1, v + 1 + cnt, p[i].s) - v;
    sort(p + 1, p + n + 1);
    /*for (int i = 1; i <= n; i++)
        printf("%d %d %d\n", p[i].f, p[i].s, p[i].t);*/
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        int temp = seg.query(1, 1, cnt, p[i].s + 1, cnt);
        if (temp > p[i].t) ans++;
        seg.update(1, 1, cnt, p[i].s, p[i].t);
    }
    printf("%d\n", ans);
    return 0;
}
View Code
01-16 10:45