A Busiest Computing Nodes

You have a computing cluster with a total of k computing nodes, labelled from 0 to k1. The cluster can handle multiple requests at the same time, but each node can process at most one request at the same time.

The rules for request assignment to computing nodes are as follows. Assume the i-th (i starts from 0) request arrives. If all nodes are occupied, the request is discarded (not processed at all). If the (i%k)-th node is available, it will process the request. Otherwise, the request will check the availability of the next node at (i+1)%k, (i+2)%k, and so on, until it finds an idle node.

Given a set of requests with their arrival time and the processing time, your task is to find the busiest computing nodes. A node that belongs to the busiest nodes when no other nodes serve more requests than it does.

Input

The first line includes k and n, representing the size of the cluster and the number of requests.

Each of the next n lines includes two positive integers, representing the arrival time and the processing time of a request.

The input data satisfy that 1k,n100,000, and 1arrival_time,processing_time1,000,000,000.

The requests are given in non-decreasing order of arrival time.

Output

Print the labels of all the busiest nodes in numerical order, separated by spaces.

3 5
1 5
2 2
3 3
4 3
5 3
 
结尾无空行

Sample Output

1
 
结尾无空行
Acknowledgment

2012 Laboratories of HUAWEI.

题目大意

这个就是给你k台机器,编号位0到k-1,然后给你给你n个指令,每一个指令有两个数x,y,指的是指令到达时间和运行运行时间,指令到达之后首先在[i%k,k-1]找一个空闲的机器,如果找到就运行,没有找到就在[0,i%k-1]中找,在找不到就直接丢弃这个指令,问你最后那个几个机器运行的次数最多。

题解

这个题的有很多方法的。有用优先队列+set,有用线段树+二分的,但是我们用的是分块

这个题为什么能用线段树+二分,是因为首先考虑一个点就是一个数组的min[1,x]的值是具有单调性的,就是min[1,x]>=min[1,x+1]就是这样。

然后这个题就变成了线段树维护区间最小值+单点修改。就是对于每一个请求,先二分查找区间[i%k, k-1]满足题目条件的最近的点,如果没有就去区间[0, i%k-1]找,如果还没有这个请求就舍弃掉。

对于这题怎么用分块,就是这个题每一个块中维护一个最小值,然后暴力每一个块,如果块的最小值大于这个这个请求的到来时间,就暴力下一个块

Code

线段树:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=4e6+100;
int res[maxn];
int p[maxn];
struct node{
    int l,r;
    ll mi;
}t[maxn];
void push(int p){
    t[p].mi=min(t[2*p].mi,t[2*p+1].mi);
}
void build(int p,int l,int r){
    t[p].l=l;
    t[p].r=r;
    if(t[p].l==t[p].r){
        t[p].mi=0;
        return ;
    }
    int mid=(t[p].l+t[p].r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    push(p);
}
ll query(int p,int l,int r){
    if(t[p].l>=l&&t[p].r<=r){
        return t[p].mi;
    }
    ll ans=1e18;
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid){
        ans=min(ans,query(2*p,l,r));
    } 
    if(r>mid){
        ans=min(ans,query(2*p+1,l,r));
    }
    return ans;
}
void update(int p,int l,ll x){
    if(t[p].l==t[p].r){
        t[p].mi=x;
        return ;
    }
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid){
        update(2*p,l,x);
    }
    else{
        update(2*p+1,l,x); 
    } 
    push(p);
}
int main(){
    int k,n;
    cin>>k>>n;
    build(1,1,k);
    for(int i=0;i<n;i++){
        ll x,y;
        scanf("%lld%lld",&x,&y);
        int z=i%k+1;
        if(query(1,z,k)<=x){
            int ll=z,rr=k,ans=-1;
            while(ll<=rr){
                int mid=(ll+rr)/2;
                if(query(1,ll,mid)<=x){
                    rr=mid-1;
                    ans=mid;
                }
                else{
                    ll=mid+1;
                }
            }
            if(ans!=-1){
        //    cout<<i<<" sd "<<ans<<endl;
                res[ans-1]++;
                update(1,ans,x+y);
            }
        }
        else if(query(1,1,z-1)<=x){
            int ll=1,rr=z-1,ans=-1;
            while(ll<=rr){
                int mid=(ll+rr)/2;
                if(query(1,ll,mid)<=x){
                    rr=mid-1;
                    ans=mid;
                }
                else{
                    ll=mid+1;
                }
            }
            if(ans!=-1){
        //        cout<<i<<" sd "<<ans<<endl;
                res[ans-1]++;
                update(1,ans,x+y);
            }
        }
    }
    int ma=0;
    for(int i=0;i<k;i++){
        ma=max(ma,res[i]);
    }
    int cnt=0;
    for(int i=0;i<k;i++){
        if(res[i]==ma){
            p[++cnt]=i;
        }
    }
    for(int i=1;i<cnt;i++){
        printf("%d ",p[i]);
    }
    cout<<p[cnt]<<endl;
    
}
View Code

分块没代码

 

 

posted @ 2021-09-23 01:20  lipu123  阅读(77)  评论(0)    收藏  举报