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
原创粉丝点击