CF 496E(Distributing Parts-序列混合贪心+set)

E. Distributing Parts
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are an assistant director in a new musical play. The play consists of n musical parts, each part must be performed by exactly one actor. After the casting the director chose m actors who can take part in the play. Your task is to assign the parts to actors. However, there are several limitations.

First, each actor has a certain voice range and there are some parts that he cannot sing. Formally, there are two integers for each actor,ci and di (ci ≤ di) — the pitch of the lowest and the highest note that the actor can sing. There also are two integers for each part — ajand bj (aj ≤ bj) — the pitch of the lowest and the highest notes that are present in the part. The i-th actor can perform the j-th part if and only if ci ≤ aj ≤ bj ≤ di, i.e. each note of the part is in the actor's voice range.

According to the contract, the i-th actor can perform at most ki parts. Besides, you are allowed not to give any part to some actors (then they take part in crowd scenes).

The rehearsal starts in two hours and you need to do the assignment quickly!

Input

The first line contains a single integer n — the number of parts in the play (1 ≤ n ≤ 105).

Next n lines contain two space-separated integers each, aj and bj — the range of notes for the j-th part (1 ≤ aj ≤ bj ≤ 109).

The next line contains a single integer m — the number of actors (1 ≤ m ≤ 105).

Next m lines contain three space-separated integers each, cidi and ki — the range of the i-th actor and the number of parts that he can perform (1 ≤ ci ≤ di ≤ 1091 ≤ ki ≤ 109).

Output

If there is an assignment that meets all the criteria aboce, print a single word "YES" (without the quotes) in the first line.

In the next line print n space-separated integers. The i-th integer should be the number of the actor who should perform the i-th part. If there are multiple correct assignments, print any of them.

If there is no correct assignment, print a single word "NO" (without the quotes).

Sample test(s)
input
3
1 3
2 4
3 5
2
1 4 2
2 5 1
output
YES
1 1 2
input
3
1 3
2 4
3 5
2
1 3 2
2 5 1
output
NO

把plays和actors的区间混合并按照l排序,相同则actors<plays

然后这段序列中已维护actors.l≤plays.l,actors.r>plays.r可以用set找

复杂度O((n+m)log(n+m))



#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<set>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (100000+10)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int n,m;
struct Pair
{
public:
	int l,r,i;
	bool flag;
	friend bool operator<(const Pair a,const Pair b){
		return a.r<b.r;
	}
}a[MAXN*2];
int k[MAXN];
int cmp(const void* a,const void *b)
{
	Pair a2=*(Pair*)a;
	Pair b2=*(Pair*)b;
	if (a2.l^b2.l) return a2.l<b2.l?-1:1;
	return a2.flag<b2.flag?-1:a2.flag==b2.flag?0:1;
}
multiset<Pair> S;
multiset<Pair>::iterator it;
int ans[MAXN];
int main()
{
//	freopen("CF496E.in","r",stdin);
	scanf("%d",&n);
	For(i,n) scanf("%d%d",&a[i].l,&a[i].r),a[i].i=i,a[i].flag=1;
	scanf("%d",&m);
	Fork(i,n+1,n+m) scanf("%d%d%d",&a[i].l,&a[i].r,&k[i-n]),a[i].i=i-n,a[i].flag=0;
	
	qsort(a+1,n+m,sizeof(a[1]),cmp);
	
	S.clear();
	For(i,n+m)
	{
		if (!a[i].flag) S.insert(a[i]);
		else
		{
			it=S.lower_bound(a[i]);
			if (it!=S.end())
			{
				ans[a[i].i]=it->i;
				if (--k[it->i]==0) S.erase(it);
			}
			else 
			{
				cout<<"NO\n";
				return 0;
			}
			
		} 
	}
	
	cout<<"YES\n";
	printf("%d",ans[1]);Fork(i,2,n) printf(" %d",ans[i]);printf("\n");
	
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值