2021 ICPC网络赛第一场**A Busiest Computing Nodes
2021 ICPC网络赛第一场A Busiest Computing Nodes
题意:
有 k 个点( j = 0 , 1... k), n 个任务( i = 0 , 1... n),每个任务有到达时间和持续时间,第 i个任务从 i % k 的点开始往后找有没有空闲的点,如果没有找到则任务作废,问 k个点谁接的任务最多
思路:线段树+二分+set
线段树维护 k个点结束的区间最小值,单点修改,区间查询
把本来要先查询区间(i%k,k-1)(0,i%k-1)转变为查询区间(i%k,i%k+k),一共放入2*k个点;
二分查找最小值
set维护 k个点结束的最小值,判断是否任务需要遗弃
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10,INF=0x3f3f3f3f;
int cnt[N];int k,m;
int tr[N<<3],a[N<<2];//a存储第i个项目结束时间
set<int>s;
unordered_map<int,int>mp;
void build(int root,int l,int r){
if(l==r){
tr[root]=INF;
return;
}
int mid = l + r >> 1;
build(root << 1,l,mid);
build(root << 1 | 1,mid+1,r);
tr[root]=min(tr[root << 1],tr[root << 1 | 1]);
}
void update(int root,int l,int r,int x,int y){
if(l>x||r<x){
return ;
}
if(l==r&&l==x){
tr[root]=y;
return;
}
int mid = l + r >> 1;
update(root << 1,l,mid,x,y);
update(root << 1 | 1,mid+1,r,x,y);
tr[root]=min(tr[root << 1],tr[root << 1 | 1]);
}
int query(int root ,int l,int r,int x,int y){
if(l>y||r<x){
return INF;
}
if(l>=x&&r<=y){
return tr[root];
}
int mid = l + r >> 1;
int mi;
mi=min(query(root << 1,l,mid,x,y),query(root << 1 | 1,mid+1,r,x,y));
return mi;
}
int f(int l,int r,int x){
while(l<r){
int mid = l + r >> 1;
if(query(1,1,2*k,l,mid)<x){
r=mid;
}
else l=mid+1;
}
return l;
}
signed main(){
ios::sync_with_stdio(false);
cin>>k>>m;
build(1,1,2*k);//建树从1开始
s.insert(0);
mp[0]=k;
for(int i=0;i<m;i++){
int st,time;
cin>>st>>time;
if(*s.begin()>=st) continue;//如果最小结束时间大于等于st当前仍无就废弃
if(a[i%k]<st){//第i%k个及其刚好可以进行这个任务
mp[a[i%k]]--;//之前结束时间的点减去1
cnt[i%k]++;//第i%k个点任务数+1
if(mp[a[i%k]]==0){//之前结束时间的点数为0,就把之前结束时间在s中除掉
s.erase(a[i%k]);
}
a[i%k]=st+time-1;//要更新结束时间
mp[a[i%k]]++;//新的结束时间的点+1
if(mp[a[i%k]]==1) s.insert(a[i%k]);//现在时间的点数为1,把这个时间放入s
update(1,1,2*k,(i%k)+1,a[i%k]);//跟新(i%k+1);
update(1,1,2*k,(i%k)+1+k,a[i%k]);//更新(i%k+1+k)
}
else{
int idx;
idx=f(i%k+1,i%k+k,st);//把本来要先查询区间(i%k,k-1)(0,i%k-1)转变为查询区间(i%k,i%k+k)
idx--;
idx%=k;
mp[a[idx]]--;
cnt[idx]++;
if(mp[a[idx]]==0){
s.erase(a[idx]);
}
a[idx]=st+time-1;
mp[a[idx]]++;
if(mp[a[idx]]==1) s.insert(a[idx]);
update(1,1,2*k,(idx%k)+1,a[idx]);
update(1,1,2*k,(idx%k)+1+k,a[idx]);
}
}
int mx=0;
for(int i=0;i<k;i++){
mx=max(mx,cnt[i]);
}
int cnttt=0;
for(int i=0;i<k;i++){
if(cnt[i]==mx){
if(cnttt){
cout<<" "<<i;
}
else cout<<i;
cnttt++;
}
}
}

浙公网安备 33010602011771号