牛客程式設計巔峰賽S1第5場 - 青銅&白銀 C.排隊 (優先佇列,歸併排序)
阿新 • • 發佈:2020-07-24
-
題意:有\(m\)個視窗,\(n\)個人排隊,每個人都有各自的辦理時間,只有辦理完成窗口才能空出來,後面的人開始辦理,求有多少人比後面的人開始辦理的早但完成的晚.
-
題解:我們可以用優先佇列來模擬辦理,用一個數組q來記錄辦理完成的時間,之後只要求q中逆序對的個數即可,既然求逆序對,那我們肯定用歸併排序啦~
-
程式碼:
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 q[1000010]; long long t[1000010]; long long res; priority_queue<long long,vector<long long>,greater<long long>> h; long long merge_sort(long long q[],int l,int r){ if(l==r) return 0; int mid=(l+r)>>1; res=merge_sort(q,l,mid)+merge_sort(q,mid+1,r); int i=l,j=mid+1; int cnt=0; while(i<=mid && j<=r){ if(q[i]<=q[j]) t[++cnt]=q[i++]; else{ t[++cnt]=q[j++]; res+=mid-i+1; } } while(i<=mid) t[++cnt]=q[i++]; while(j<=r) t[++cnt]=q[j++]; for(int i=l,j=1;i<=r;++i,++j) q[i]=t[j]; return res; } long long getNumValidPairs(int n, int m, vector<int>& a) { for(int i=0;i<m;++i){ h.push(0); } for(int i=0;i<n;++i){ long long tmp=h.top()+a[i]; q[i+1]=tmp; h.pop(); h.push(tmp); } res=merge_sort(q,1,n); return res; } };