大家好 我是寸铁 希望这篇题解对你有用,麻烦动动手指点个赞或关注,感谢您的关注
考点 模拟+小根堆
分析
由于计算机之间是独立的,这题模拟+堆即可
维护当前ai
时刻计算机剩余算力或者消耗算力****是多少。
运用堆/优先队列维护当前ai
时刻前的右端点区间删掉
能将堆顶删掉就一直删掉,直至当前堆顶的右端点在ai
时刻的右边。
实现
删完后记得将算力值进行恢复,即让s[b]+=p[b].poll()[1]
即可
算力不够当前的b
值,则输出-1
。
入队时需要将算力值减去,即s[b]-=d
PriorityQueue
Accode
import java.util.*;
import java.io.*;
public class Main{
static int N=200010;
static int n,m;
static int s[]=new int[N];
static PriorityQueue<int[]>[]q=new PriorityQueue[N];
//小根堆/优先队列
//堆顶为当前最小值
//Comparator比较器
static Comparator<int[]>cmp=new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// TODO Auto-generated method stub
return o1[0]-o2[0];
//按结构体的第一数比较大小
}
};
public static void main(String []args) throws IOException {
//初始化结构体
for(int i=0;i<N;i++) {
q[i]=new PriorityQueue<>(cmp);
}
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
String []str=bf.readLine().split(" ");
n=Integer.parseInt(str[0]);
m=Integer.parseInt(str[1]);
str=bf.readLine().split(" ");
for(int i=1;i<=n;i++)s[i]=Integer.parseInt(str[i-1]);
//读入n台计算机的运算能力
while(m-->0) {
int a,b,c,d;
str=bf.readLine().split(" ");
a=Integer.parseInt(str[0]);
b=Integer.parseInt(str[1]);
c=Integer.parseInt(str[2]);
d=Integer.parseInt(str[3]);
while(q[b].size()>0&&q[b].peek()[0]<=a) {
//队列不为空并且堆顶元素的大小<=a
//终点小于当前的起点a时
s[b]+=q[b].poll()[1];
//运算能力恢复q[b].poll()[1]这么多点
}
if(s[b]<d)System.out.println("-1");
//运算能力不够当前需要的d点时,输出-1
else {
int []task= {a+c,d};
//task结构体第一个数存的是终点时刻
//第二个数存的是运算能力
q[b].add(task);
//入队
s[b]-=d;
//运算能力减去d点
System.out.println(s[b]);
//输出剩余的运算能力即可
}
}
}
}