[CF496E] Distributing Parts

Description

(n) 首独奏乐曲,第 (i) 首的音高范围为 ([a_i,b_i]),有 (m) 位演奏家,第 (i) 位能演奏的音高范围为 ([c_i,d_i]),且他最多可以出演 (k_i) 次。问是否存在合法方案能使所有乐曲都被演奏一次。

Solution

对于所有乐曲和演奏家,按照左端点排序,从小到大依次扫描

维护一棵演奏家的平衡树,关键字为 (d_i),同时记录其剩余的出演次数

扫描中,每遇到新的演奏家,就将其加入平衡树

每遇到新的乐曲,显然对平衡树中所有的演奏家,一定满足 (c le a),只需要约束 (b le d)

故在平衡树中二分,找到 (ge b) 的第一位演奏家,将其出演次数 (-1),如果为 (0) 则将其从平衡树中删除

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;

const int type_player = 0;
const int type_song = 1;

int n_song, n_player, n_event;

struct player
{
    int c,d,k;
    void scan()
    {
        cin>>c>>d>>k;
    }
} players[N];

struct song
{
    int a,b;
    void scan()
    {
        cin>>a>>b;
    }
} songs[N];

struct event
{
    int type; //0-player 1-song
    player m_player;
    song m_song;
    int id;
    void assign(player _player,int _id)
    {
        type=0;
        m_player=_player;
        id=_id;
    }
    void assign(song _song,int _id)
    {
        type=1;
        m_song=_song;
        id=_id;
    }
    int getkey()
    {
        int ans=0;
        if(type==0) ans=m_player.c*2;
        if(type==1) ans=m_song.a*2;
        if(type==1) ++ans;
        return ans;
    }
    bool operator < (event& obj)
    {
        return getkey() < obj.getkey();
    }
} events[N];

void read_data()
{
    cin>>n_song;
    for(int i=1;i<=n_song;i++) songs[i].scan();
    cin>>n_player;
    for(int i=1;i<=n_player;i++) players[i].scan();
}

void make_events()
{
    for(int i=1;i<=n_song;i++) events[i].assign(songs[i],i);
    for(int i=1;i<=n_player;i++) events[i+n_song].assign(players[i],i);
    n_event = n_song + n_player;
    sort(events+1, events+n_event+1);
}

struct node
{
    int d,k,id;
    bool operator < (const node b) const
    {
        return d < b.d;
    }
    void dec()
    {
        k--;
    }
};

int rec[N];

void solve()
{
    multiset <node> s;

    for(int i=1;i<=n_event;i++)
    {
        event &now = events[i];
        if(now.type == type_player)
        {
            node tmp = {now.m_player.d, now.m_player.k, now.id};
            s.insert(tmp);
        }
        if(now.type == type_song)
        {
            song &pre = now.m_song;
            multiset <node>::iterator it = s.lower_bound({pre.b});
            if(it==s.end())
            {
                cout<<"NO";
                return;
            }
            else
            {
                rec[now.id] = it->id;
                if(it->k == 1) s.erase(it);
                else
                {
                    node tmp = *it;
                    s.erase(it);
                    tmp.dec();
                    s.insert(tmp);
                }
            }
        }
    }

    cout<<"YES"<<endl;
    for(int i=1;i<=n_song;i++) cout<<rec[i]<<" ";
}

signed main()
{
    ios::sync_with_stdio(false);

    read_data();
    make_events();
    solve();
}

原文地址:https://www.cnblogs.com/mollnn/p/13581053.html