思路:我们先枚举左边界,把合法的都扣出来,那么对于这些合法的来说值有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\n", vec.size()); for(int i = 0; i < vec.size(); i++) printf("%d ", vec[i]); puts(""); return 0; } /* */