分析:这道题考察的是优先队列,我们优先队列里面可以存pair类型的数据,pair中第一维是任务终止时间,第二维是该任务占用的算力。由于pair类型是按照第一维进行排序的,按照终止时间从早到晚排,我们就不需要手写结构体排序,直接利用greater即可。
下面我说一下这道题的处理方法,我们先建立一个p数组,p[i]记录第i个计算机的当前算力,假如我们当前遍历到某个任务,这个任务是要分配给第t个计算机的,我们就先遍历第t个计算机的优先队列,把优先队列中终止时间在当前时间之前的任务全部释放掉,在释放任务过程中加上该任务占用的算力,当优先队列中终止时间小于等于当前时间的任务全部被释放后,这个时候p[t]就真正表示第t个计算机的算力,这个时候判断p[t]与d的关系,如果p[t]<d,就直接输出-1,如果p[t]>=d,就输出p[t]-d,并将p[t]-d,并将该任务加入第t个计算机的优先队列中,该任务的终止时间就是a+c-1,算力就是d。
下面是代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>PII;
const int N=200030;
priority_queue<PII,vector<PII>,greater<PII> >q[N];
ll p[N];//p[i]表示第i个计算机的算力
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%lld",&p[i]);
for(int i=1;i<=m;i++)
{
ll a,b,c,d;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
while(!q[b].empty()&&q[b].top().first<a)
{
p[b]+=q[b].top().second;//把无效任务的占用的算力释放
q[b].pop();//释放无效任务
}
if(p[b]>=d)
{
p[b]-=d;
printf("%lld\n",p[b]);
q[b].push({a+c-1,d});//把当前任务加入第b个计算机的优先队列
}
else
puts("-1");
}
return 0;
}