Codeforces 1132D(二分答案+堆)
阿新 • • 發佈:2019-03-09
pac include 實現 long long fine iostream %d cpp queue
題面
傳送門
分析
二分答案,考慮如何判定
可以用貪心的方法,每次找最快沒電的電腦,在沒電前1單位時間給它充電
正確性顯然
實現上可以維護一個堆,存儲每個電腦電用完的時刻,每次從堆頂取出最小的一個給它充電。設二分值為mid,對於每個電腦記錄它的充電次數num[i],則沒電的時間就是\(\lfloor \frac{a_i+num_i\times mid}{b_i} \rfloor+1\)
如果在維護堆的過程中發現當前時間已經超過某個電腦的沒電時間,則返回false
代碼
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxn 200005 using namespace std; struct node{ long long dtim; int id; node(){ } node(int i,long long t){ id=i; dtim=t; } friend bool operator < (node p,node q){ return p.dtim>q.dtim; } }; int n,k; long long a[maxn],b[maxn]; long long num[maxn]; bool check(long long add){ priority_queue<node>q; for(int i=1;i<=n;i++){ q.push(node(i,a[i]/b[i]+1)); num[i]=0; } for(int i=1;i<=k;i++){ node now=q.top(); q.pop(); if(now.dtim<i) return 0; num[now.id]++; long long sum=a[now.id]+num[now.id]*add; q.push(node(now.id,sum/b[now.id]+1)); } return 1; } int main(){ scanf("%d %d",&n,&k); for(int i=1;i<=n;i++){ scanf("%I64d",&a[i]); } for(int i=1;i<=n;i++){ scanf("%I64d",&b[i]); } long long l=0,r=1e13,ans=-1,mid; while(l<=r){ mid=(l+r)>>1; if(check(mid)){ ans=mid; r=mid-1; }else l=mid+1; } printf("%I64d\n",ans); }
Codeforces 1132D(二分答案+堆)