习题: Developing Game(扫描线&线段树)

题目

传送门

思路

我们考虑怎么将转换这个限制

考虑最终的答案一定满足一个式子,对于方案中的任意一个人都满足\(l_i<=min\{v_i\}<=v_i<=max\{v_i\}<=r_i\)

我们把平面内的每一个点看做\((min\{v_i\},max\{v_i\})\)

把其转换成为一个矩阵,矩阵的左下角的左边即为\((l_i,v_i)\),右上角的坐标即为\((v_i,r_i)\)

之后就是求最多有多少个矩阵重叠在一起,这就是一个扫描线的板子了

代码

#include<iostream>
#include<vector>
using namespace std;
namespace lst
{
    struct node
    {
        int l,r;
        int maxx,lazy,_ind;
    }tre[1200005];
    void build(int l,int r,int k)
    {
        tre[k].l=l;
        tre[k].r=r;
        if(l==r)
        {
            tre[k]._ind=l;
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,k<<1);
        build(mid+1,r,k<<1|1);
        tre[k].maxx=max(tre[k<<1].maxx,tre[k<<1|1].maxx);
        tre[k]._ind=(tre[k].maxx==tre[k<<1].maxx?tre[k<<1]._ind:tre[k<<1|1]._ind);
    }
    void push_down(int k)
    {
        tre[k<<1].lazy+=tre[k].lazy;
        tre[k<<1].maxx+=tre[k].lazy;
        tre[k<<1|1].lazy+=tre[k].lazy;
        tre[k<<1|1].maxx+=tre[k].lazy;
        tre[k].lazy=0;
    }
    void change(int l,int r,int val,int k=1)
    {
        if(l>tre[k].r||tre[k].l>r)
            return;
        if(l<=tre[k].l&&tre[k].r<=r)
        {
            tre[k].maxx+=val;
            tre[k].lazy+=val;
            return;
        }
        push_down(k);
        change(l,r,val,k<<1);
        change(l,r,val,k<<1|1);
        tre[k].maxx=max(tre[k<<1].maxx,tre[k<<1|1].maxx);
        tre[k]._ind=(tre[k].maxx==tre[k<<1].maxx?tre[k<<1]._ind:tre[k<<1|1]._ind);
    }
}
using namespace lst;
struct NODE
{
    int l,v,r;
}a[100005];
struct ls
{
    int l,r;
};
int n;
int maxx,limit,ans;
pair<int,int> li;
vector<ls> ad[300005];
vector<ls> de[300005];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].l>>a[i].v>>a[i].r;
        maxx=max(a[i].v,maxx);
        limit=max(a[i].r,limit);
        ad[a[i].l].push_back((ls){a[i].v,a[i].r});
        de[a[i].v].push_back((ls){a[i].v,a[i].r});
    }
    build(1,limit,1);
    for(int i=1;i<=maxx;i++)
    {
        for(int j=0;j<ad[i].size();j++)
            change(ad[i][j].l,ad[i][j].r,1);
        for(int j=0;j<de[i-1].size();j++)
            change(de[i-1][j].l,de[i-1][j].r,-1);
        if(tre[1].maxx>ans)
        {
            ans=tre[1].maxx;
            li=make_pair(i,tre[1]._ind);
        }
    }
    int f=1;
    cout<<ans<<'\n';
    for(int i=1;i<=n;i++)
    {
        if(a[i].l<=li.first&&li.first<=a[i].v&&a[i].v<=li.second&&li.second<=a[i].r)
        {
            if(f)
            {
                cout<<i;
                f=0;
            }
            else
                cout<<' '<<i;
        }
    }
    return 0;
}
posted @ 2020-08-24 15:42  loney_s  阅读(92)  评论(0)    收藏  举报