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();
}