3492. 负载均衡

题目链接

3492. 负载均衡

\(n\) 台计算机,第 \(i\) 台计算机的运算能力为 \(v_i\)

有一系列的任务被指派到各个计算机上,第 \(i\) 个任务在 \(a_i\) 时刻分配,指定计算机编号为 \(b_i\),耗时为 \(c_i\) 且算力消耗为 \(d_i\)

如果此任务成功分配,将立刻开始运行,期间持续占用 \(b_i\) 号计算机 \(d_i\) 的算力,持续 \(c_i\) 秒。

对于每次任务分配,如果计算机剩余的运算能力不足则输出 \(−1\),并取消这次分配,否则输出分配完这个任务后这台计算机的剩余运算能力。

输入格式

输入的第一行包含两个整数 \(n,m\),分别表示计算机数目和要分配的任务数。

第二行包含 \(n\) 个整数 \(v_1,v_2,⋅⋅⋅v_n\),分别表示每个计算机的运算能力。

接下来 \(m\) 行每行 \(4\) 个整数 \(a_i,b_i,c_i,d_i\),意义如上所述。数据保证 \(a_i\) 严格递增,即 \(a_i<a_i+1\)

输出格式

输出 \(m\) 行,每行包含一个数,对应每次任务分配的结果。

数据范围

对于 \(20\%\) 的评测用例,\(n,m≤200\)
对于 \(40\%\) 的评测用例,\(n,m≤2000\)
对于所有评测用例,\(1≤n,m≤200000,1≤a_i,c_i,d_i,v_i≤10^9,1≤b_i≤n\)

输入样例:

2 6
5 5
1 1 5 3
2 2 2 6
3 1 2 3
4 1 6 1
5 1 3 3
6 1 3 4

输出样例:

2
-1
-1
1
-1
0

样例解释

时刻 \(1\),第 \(1\) 个任务被分配到第 \(1\) 台计算机,耗时为 \(5\),这个任务时刻 \(6\) 会结束,占用计算机 \(1\) 的算力 \(3\)

时刻 \(2\),第 \(2\) 个任务需要的算力不足,所以分配失败了。

时刻 \(3\),第 \(1\) 个计算机仍然正在计算第 \(1\) 个任务,剩余算力不足 \(3\),所以失败。

时刻 \(4\),第 \(1\) 个计算机仍然正在计算第 \(1\) 个任务,但剩余算力足够,分配后剩余算力 \(1\)

时刻 \(5\),第 \(1\) 个计算机仍然正在计算第 \(1,4\) 个任务,剩余算力不足 \(4\),失败。

时刻 \(6\),第 \(1\) 个计算机仍然正在计算第 \(4\) 个任务,剩余算力足够,且恰好用完。

解题思路

大根堆

每台计算机之间互不干扰,可以考虑对一台计算机的操作:对于一段区间,如果右端点小于当前时刻,则该区间没有贡献,可以直接删掉,如果不小于当前时刻,由于当前时刻一定不小于区间左端点,所以该区间一定有贡献,所以可以用大根堆存下右端点和权值,另外用一个值存下该计算机的贡献

  • 时间复杂度:\(O(mlogm)\)

代码

// Problem: 负载均衡
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/3495/
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=2e5+5;
priority_queue<PII,vector<PII>,greater<PII>> q[N];
int v[N],lst[N],n,m;
int main()
{
    help;
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>v[i];
    while(m--)
    {
    	int a,b,c,d;
    	cin>>a>>b>>c>>d;
        while(q[b].size()&&q[b].top().fi<a) 
        {
        	lst[b]-=q[b].top().se;
        	q[b].pop();
        }
        if(lst[b]+d>v[b])puts("-1");
        else
        {
        	lst[b]+=d;
        	cout<<v[b]-lst[b]<<'\n';
        	q[b].push({a+c-1,d});
        }                                                                                                                                                                                                                                    
    }
    return 0;
}
posted @ 2022-02-21 18:13  zyy2001  阅读(37)  评论(0编辑  收藏  举报