Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并
给你n个人的 位置v[i],同时每个人有一个可接受范围 l[i], r[i];
现在让你选尽量多的人,使得被选的人 都能互相接受
输出人数及选择方案
题解:
这个题看到不太会
对于两个人来说要让它们相互接受可以有以下情况
l1 v1 r1
l2 v2 r2
l2 v2 r2
l2 v2 r2
l2 v2 r2
发现一些规则
就是相交范围就是l1 v1 与 l2 v2的相交的一段,但是当v2超过r1的时候,就不可行了
所有我们可以想到一种 加上,减去的操作,
当v1 出现我们在线段树上加入l1,v1的这段有效的区间
当走过r1的时候 把l1 v1在线段树上减去即可
显然对于一条线段要拆成两条线段, l1 v1 1 v1 和 l1 v1 -1 v2
再在线段树上操作就可以了
统计答案的时候呢,也可以利用线段树有效区间出来
@doubility
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double Pi = acos(-1.0); const int N = 5e5+10, M = 2e5+20, mod = 1e9+7, inf = 2e9; int n; int tag[N*4],mx[N*4]; void push_up(int i) { mx[i] = max(mx[ls],mx[rs]); } void push_down(int i,int ll,int rr) { if(tag[i] != 0 && ll != rr) { tag[ls] += tag[i]; tag[rs] += tag[i]; mx[ls] += tag[i]; mx[rs] += tag[i]; tag[i] = 0; } } void update(int i,int ll,int rr,int l,int r,int v) { push_down(i,ll,rr); if(l == ll && r == rr) { tag[i] += v; mx[i] += v; return ; } if(r <= mid) update(ls,ll,mid,l,r,v); else if(l > mid) update(rs,mid+1,rr,l,r,v); else { update(ls,ll,mid,l,mid,v); update(rs,mid+1,rr,mid+1,r,v); } push_up(i); } int query(int i,int ll,int rr,int x) { push_down(i,ll,rr); if(ll == rr) return ll; if(mx[ls] == x) return query(ls,ll,mid,x); else return query(rs,mid+1,rr,x); push_up(i); } struct ss{ int l,r,h,in; ss(int l = 0, int r = 0, int h = 0,int in = 0) : l(l), r(r), h(h),in(in) {} bool operator < (const ss & b) const { return h < b.h || h == b.h && in > b.in; } }p[N],P[N]; int main() { scanf("%d",&n); for(int i = 1; i <= n; ++i) { int l,v,r; scanf("%d%d%d",&l,&v,&r); p[i] = ss(l,v,v,1); p[i+n] = ss(l,v,r,-1); P[i] = ss(l,r,v,1); } int m = n << 1; sort(p+1,p+m+1); int ans = 0,x,y; for(int i = 1; i <= m; ++i) { int l = p[i].l, r = p[i].r; update(1,1,300000,l,r,p[i].in); if(mx[1] > ans) { ans = mx[1]; x = query(1,1,300000,mx[1]); y = p[i].h; } } printf("%d\n",ans); for(int i = 1; i <= n; ++i) { if(P[i].l <= x && P[i].r >= y && P[i].h >= x && P[i].h <= y) printf("%d\n",i); } return 0; }