裸的cdq, 没啥好说的, 要注意mid左边和mid右边的a相同的情况。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 5e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; int n; struct node { int a, b, c; bool die; } p[N], tmp[N]; bool cmpa(const node& x, const node& y) { return x.a > y.a; } bool cmpb(const node& x, const node& y) { return x.b > y.b; } void cdq(int l, int r) { if(l == r) return; int mid = l + r >> 1; int v1 = p[mid].a, v2 = p[mid + 1].a; cdq(l, mid); cdq(mid + 1, r); int mx = 0, mx2 = 0; for(int i = mid + 1, j = l; i <= r; i++) { while(j <= mid && p[j].b > p[i].b) { mx = max(mx, p[j].c); if(p[j].a > v1) mx2 = max(mx2, p[j].c); j++; } if(p[i].a == v1) { if(mx2 > p[i].c) p[i].die = true; } else { if(mx > p[i].c) p[i].die = true; } } int p1 = l, p2 = mid + 1, tot = l; while(p1 <= mid && p2 <= r) if(p[p1].b >= p[p2].b) tmp[tot++] = p[p1], p1++; else tmp[tot++] = p[p2], p2++; while(p1 <= mid) tmp[tot++] = p[p1], p1++; while(p2 <= r) tmp[tot++] = p[p2], p2++; for(int i = l; i <= r; i++) p[i] = tmp[i]; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &p[i].a); for(int i = 1; i <= n; i++) scanf("%d", &p[i].b); for(int i = 1; i <= n; i++) scanf("%d", &p[i].c); int cnt = 0; sort(p + 1, p + 1 + n, cmpa); cdq(1, n); for(int i = 1; i <= n; i++) if(p[i].die) cnt++; printf("%d\n", cnt); return 0; } /* */