CF 377D Developing Game(线段树+扫描线)
来源:互联网 发布:微软软件卸载工具 编辑:程序博客网 时间:2024/06/07 14:46
题意:有n个开发人员,每个人有个技能值vi,每个人不想和技能值不在区间[li,ri]的人合作,现在要选尽可能多的人,使得满足所有选中的人的要求。
思路:首先,如果我们能求出一组L,R,使得每个选中的人i都满足li<=L<=R<=ri并且L<=vi<=R,那么我们就能找到应该选出的人。那么如何求这个L和R呢,把L,R想象成坐标系中的一个点,那么对于每一个人,需要满足li<=L<=vi并且vi<=R<=ri,这样,每个人可以看成一个矩形,问题就变成了寻找一个点使得有最多的矩形覆盖,这个问题可以用线段树+扫描线处理。。。
代码:
#include <iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=100000+10;const int maxm=300000+10;struct Node{ int v,l,r,type; Node(){}; Node(int vv,int xl,int xr,int tt) {v=vv;l=xl;r=xr;type=tt;} bool operator <(const Node &a)const { return (v==a.v&&type<a.type)||(v<a.v); }}node[maxn<<1];int val[maxn],vl[maxn],vr[maxn];int maxv[maxm<<2],addv[maxm<<2],maxp[maxm<<2];inline void PushUp(int rt){ if(maxv[rt<<1]>maxv[rt<<1|1]) { maxv[rt]=maxv[rt<<1]; maxp[rt]=maxp[rt<<1]; } else { maxv[rt]=maxv[rt<<1|1]; maxp[rt]=maxp[rt<<1|1]; }}void PushDown(int rt){ if(addv[rt]) { maxv[rt<<1]+=addv[rt]; maxv[rt<<1|1]+=addv[rt]; addv[rt<<1]+=addv[rt]; addv[rt<<1|1]+=addv[rt]; addv[rt]=0; }}void build(int l,int r,int rt){ maxv[rt]=addv[rt]=0; if(l==r){maxp[rt]=l;return ;} int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); PushUp(rt);}void Update(int L,int R,int l,int r,int rt,int v){ if(l>=L&&r<=R) { maxv[rt]+=v; addv[rt]+=v; return ; } PushDown(rt); int m=(l+r)>>1; if(m>=L) Update(L,R,l,m,rt<<1,v); if(m<R) Update(L,R,m+1,r,rt<<1|1,v); PushUp(rt);}int Query(int L,int R,int l,int r,int rt,int &pos){ if(l>=L&&r<=R) { pos=maxp[rt]; return maxv[rt]; } PushDown(rt); int m=(l+r)>>1; if(m>=R) return Query(L,R,l,m,rt<<1,pos); else if(m<L) return Query(L,R,m+1,r,rt<<1|1,pos); else { int mx1,p1,mx2,p2; mx1=Query(L,R,l,m,rt<<1,p1); mx2=Query(L,R,m+1,r,rt<<1|1,p2); if(mx1<mx2) { mx1=mx2; p1=p2; } pos=p1; return mx1; }}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,tot=0,N=300000; scanf("%d",&n); build(1,N,1); for(int i=1;i<=n;++i) { scanf("%d%d%d",&vl[i],&val[i],&vr[i]); node[tot++]=Node(vl[i],val[i],vr[i],0); node[tot++]=Node(val[i],val[i],vr[i],1); } sort(node,node+tot); int maxnum=0,L,R; for(int i=0;i<tot;++i) { if(node[i].type) Update(node[i].l,node[i].r,1,N,1,-1); else { Update(node[i].l,node[i].r,1,N,1,1); int tmp,pos; tmp=Query(node[i].l,node[i].r,1,N,1,pos); if(tmp>maxnum) { maxnum=tmp; L=node[i].v; R=pos; } } } printf("%d\n",maxnum); bool first=true; for(int i=1;i<=n;++i) { if(val[i]>=L&&val[i]<=R&&vl[i]<=L&&vr[i]>=R) { if(!first) printf(" "); first=false; printf("%d",i); } } printf("\n"); return 0;}
0 0
- CF 377D Developing Game(线段树+扫描线)
- CF 243D Cubes(线段树)
- CF 228D Zigzag(线段树)
- CF 19D Points(线段树)
- CF 85D 五颗线段树
- CF 19D Points(线段树+set)
- CF-46D-Parking Lot(线段树)
- cf 689 D(线段树+二分)
- CF - 219D 线段树 + dfs序
- cf-343D (深搜序+线段树)
- Codeforces 249D Donkey and Stars (线段树+扫描线)
- CF 179(div2) C(线段树 || 扫描法 )
- 线段树[扫描线]
- 线段树+扫描线
- 线段树 扫描线
- 线段树扫描线
- 线段树-扫描线
- CF - 496D Tennis Game -
- 树:二叉树
- 多系统启动选择菜单删除修复要多随意有多随意(easybcd怎么用)
- 判断某年是否为闰年
- 关于UTF-8,ANSI,以及Unicode的一些文章
- 数据挖掘方法(1)主成分分析
- CF 377D Developing Game(线段树+扫描线)
- ZMQ 第二章 ZeroMQ进阶
- 异面直线之间的距离
- NGUI控件说明(中文) UITexture
- 跨平台图表控件TeeChart使用教程:将图表数据导出为XML格式
- EasyBCD建立多系统启动菜单
- js一百零一夜之第十二夜-截取字符串和返回其长度(汉字和英文)
- 解析mysql中:单表distinct、多表group by查询去除重复记录
- iOS图片拉伸技巧—— resizableImageWithCapInsets