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

时间:2023-03-09 03:49:24
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 + ;
const int M = 1e7 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ; int n;
struct segmentTree {
int mx[N << ], lazy[N << ], id[N << ]; void pushdown(int rt) {
if(lazy[rt]) {
lazy[rt << ] += lazy[rt];
lazy[rt << | ] += lazy[rt];
mx[rt << ] += lazy[rt];
mx[rt << | ] += lazy[rt];
lazy[rt] = ;
}
} void pushup(int rt) {
if(mx[rt << ] >= mx[rt << | ]) {
mx[rt] = mx[rt << ];
id[rt] = id[rt << ];
} else {
mx[rt] = mx[rt << | ];
id[rt] = id[rt << | ];
}
} void build(int l, int r, int rt) {
mx[rt] = lazy[rt] = ;
if(l == r) {
id[rt] = l;
return;
}
int mid = l + r >> ;
build(l, mid, rt << );
build(mid + , r, rt << | );
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 >> ;
pushdown(rt);
if(L <= mid) update(L, R, val, l, mid, rt << );
if(R > mid) update(L, R, val, mid + , r, rt << | );
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(, , );
scanf("%d", &n);
for(int i = ; i <= n; i++)
scanf("%d%d%d", &a[i].l, &a[i].v, &a[i].r), a[i].id = i;
sort(a + , a + + n); int ans = , ret1, ret2;
priority_queue<PII, vector<PII>, greater<PII> > que;
for(int i = , j = ; i <= ; 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, , , , );
j++;
} while(!que.empty() && que.top() < mk(i, )) {
PII now = que.top(); que.pop();
seg.update(now.fi, now.se, -, , , );
} if(ans < seg.mx[]) {
ans = seg.mx[];
ret1 = i;
ret2 = seg.id[];
}
} vector<int> vec;
for(int i = ; 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 = ; i < vec.size(); i++)
printf("%d ", vec[i]);
puts("");
return ;
} /*
*/