题目链接:这里
题意:有n首曲子,每首曲子的范围为ai~bi。有m个演奏家,每个演奏家的范围为ci~di,并且可以出演次数为ki次。如果ci<= ai<=bi<=di,则说明该曲子可以由演奏家演出。问是否存在合法方案使得所有曲子都能被演奏。第一行为一个整数表示曲子的数量n,之后n行每行两个整数ai和bi表示这首曲子占的时间范围,然后为一整数m表示演奏家人数,之后m行每行三个整数ci,di和ki分别表示演奏家演奏的时间和出演次数 。如果存在合法方案使得所有曲子都可以被演奏完毕则输出YES并输出每首曲子分别由哪位演奏家演奏(输出一种可能情况即可),否则输出NO。
解法:将所有时间段放在同一个结构数组里按结束点升序排序,开一个set记录曲子,枚举结构体中的元素,如果这个时间段是演奏家的演奏阶段,那么set中存放的曲子结束时间显然都小于等于开始时间,一直二分找到开始时间最早的曲子(贪心的让当前演奏家演奏开始时间尽可能早的曲子)让这个演奏家演奏,然后从set中删去这首曲子,直到没有合适的曲子可以演奏或者这个演奏家的演奏次数用完为止;如果这个时间段是曲子的被演奏阶段,那么将这首曲子加入set即可,最后判断被演奏曲子的数量是否为n即可判断是否存在合法方案 。

//CF 496E

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;

int n, m, person[maxn]; //person[i] 代表第i首曲子是由第preson[i]个人演奏的

struct node{
    int l, r, num, op, id;
    node(){}
    node(int l, int r, int num, int op, int id) : l(l), r(r), num(num), op(op), id(id) {}
}a[maxn<<1];

bool cmp(node x, node y){
    if(x.r != y.r) return x.r < y.r;
    if(x.op != y.op) return x.op < y.op;
    return x.l < y.l;
}

struct node2{
    int id, l;
    node2(){}
    node2(int id, int l) : id(id), l(l) {}
    bool operator < (const node2 &rhs) const{
        if(l != rhs.l) return l < rhs.l;
        return id < rhs.id;
    }
};

set <node2> s;


int main()
{
    while(scanf("%d", &n) != EOF)
    {
        memset(person, 0, sizeof(person));
        for(int i = 1; i <= n; i++){
            scanf("%d%d", &a[i].l, &a[i].r);
            a[i].op = 0, a[i].id = i;
        }
        scanf("%d", &m);
        for(int i = 1; i <= m; i++){
            scanf("%d%d%d", &a[i+n].l, &a[i+n].r, &a[i+n].num);
            a[i+n].op = 1, a[i+n].id = i;
        }
        sort(a + 1, a + n + m + 1, cmp);;//将这n+m个时间段按结束点排序,那么靠前的一定是结束时间早的
        s.clear();
        int ans = 0;//ans记录能够被演奏的曲子数目
        for(int i = 1; i <= n + m; i++){
            if(!a[i].op) s.insert(node2(a[i].id, a[i].l));
            else{
                while(s.size() && a[i].num--){
                    set<node2>::iterator p = s.lower_bound(node2(0, a[i].l));//找到开始时间大于等于a[i].l的曲子中开始时间最小的
                    if(p == s.end()) break;
                    node2 now = *p;
                    s.erase(p);//删掉这首曲子
                    person[now.id] = a[i].id;//记录这首曲子的演奏者
                    ans++;//被演奏完成的曲子数量加一
                }
            }
        }
        if(ans == n){//所有曲子均被演奏完成则说明存在合法方案
            puts("YES");
            for(int i = 1; i <= n; i++) cout << person[i] << " ";
            cout << endl;
        }
        else{
            puts("NO");
        }
    }
    return 0;
}