排队

Problem:

牛妹在银行排队等号时,观察到以下场景。
银行有m个服务窗口,假设当前有n个人等待办理业务,那么这n个人会被顺序分配一个从1到n的号码。

等待办理业务的流程如下:
从第1号到第n号顺序的进行排队。
假设当前第1号到第i-1号都正在办理或已经办理完业务,且某个窗口A没有客人正在办理业务,那么第i号会马上到窗口A办理他的业务。
如果有多个这样的窗口,第i号会随意选择一个窗口。

在0时刻,牛妹观察到m个窗口都没有客人正在办理业务,而n个人正在等待办理业务。
为了简化问题,我们假设第i号不管在哪个窗口办理业务,办理业务的时间都为​。

牛妹想知道有多少对(i,j),满足,且第i号办理业务完成的时间严格大于第j号办理业务完成的时间。

Example:

input

5,2,[1,3,2,5,4]

output

1

note

第1号 开始办理时间 0 办理完成时间 1
第2号 开始办理时间 0 办理完成时间 3
第3号 开始办理时间 1 办理完成时间 3 (在1号办理完同时开始办理)
第4号 开始办理时间 3 办理完成时间 8 (在2和3号办理完同时开始办理)
第5号 开始办理时间 3 办理完成时间 7 (在2和3号办理完同时开始办理)
唯一一组满足题意的(i,j)对为(4,5)

Remark:

对于30%数据,

对于100%数据,

题解:

用优先队列模拟窗口排队计算每个人的结束时间,题中所求为完成时间数列的逆序数,数据范围到用归并排序计算逆序数。

Code:

class Solution {
public:
    /**
     * 求解合法的(i,j)对的数量
     * @param n int整型 n个人
     * @param m int整型 m个窗口
     * @param a int整型vector 长度为n的vector,顺序表示1-n号客人的办理业务所需时间
     * @return long长整型
     */
    long long tm[111111];
    priority_queue<long long,vector<long long>, greater<long long>> box;
    void Union(int L,int R,int mid,long long &sum)
    {
        long long mm[111111];
        int k=1,l=L,r=mid+1;
        while(l<=mid&&r<=R){
            if(tm[l]<=tm[r]){
                mm[k++]=tm[l++];
            }
            else{
                sum+=mid+1-l;
                mm[k++]=tm[r++];
            }
        }
        while(l<=mid)
            mm[k++]=tm[l++];
        while(r<=R)
            mm[k++]=tm[r++];
        for(int i=L,j=1;i<=R;i++,j++)
            tm[i]=mm[j];
        return;
    }
    void merge(int l,int r,long long &sum)
    {
        if(l==r)
            return;
        int mid=(l+r)/2;
        merge(l, mid,sum);
        merge(mid+1, r, sum);
        Union(l, r, mid, sum);
    }

    long long getNumValidPairs(int n, int m, vector<int>& a) {
        // write code here
        for(int i=0;i<m;i++)
            box.push(0);
        for(int i=0;i<n;i++){
            long long mm=box.top()+a[i];
            tm[i+1]=mm;
            box.pop();
            box.push(mm);
        }
        long long ans=0;
        merge(1, n, ans);
        return ans;
    }
};