Educational Codeforces Round 61 (Rated for Div. 2) 題意:有n臺電腦要使用,一共m分鐘,每臺電腦初始電量ai,每分鐘消耗bi,若你有一臺充電寶,那麼每分鐘至少衝多少電量,才能保證每分鐘所有電腦的電量都是>=0。 題解:首先根據題意可以很清楚的看出來應該可以二分,因爲若答案x可行,則答案x+1一定可行(顯然 :) ),但是如何check答案是一個難點,這裏我們可以用貪心算法,每次充電都給最早沒電的電腦衝,這顯然是正確的,那麼我們這裏有兩種算法進行實現: Solve 1: O((n+m)lg^2(n)) 首先我們可以考慮有一個事件堆來維護,維護每一個事件沒電的那一天就可以了,實現比較簡單,但是複雜度偏高。 Solve 2:O((n+m)lg(n)) 其實對於m來說數據並不是很大,2e5,所以我們可以考慮進行桶排序,用lis[i]來保存第i天沒電的電腦的下標,然後一天一天的枚舉,然後維護即可~~~ |
---|
#include<bits/stdc++.h>
using namespace std;
#define Sheryang main
const int maxn=1e6+7;
typedef long long ll;
const int mod=1e9+7;
void Smax(int &a,int b){if(a<b) a=b;}
void Smin(int &a,int b){if(a>b) a=b;}
///#define getchar()(p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
///char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
#define IO cin.tie(0),ios::sync_with_stdio(false);
#define pi acos(-1)
#define PII pair<ll,ll>
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
/** keep hungry and keep calm! **/
ll a[maxn],b[maxn];
ll n,m;
struct node{
ll a,b,c;
bool operator <(const node &a)const{
return a.c<c;
}
};
bool judge(ll x){
priority_queue<node>q;
for(int i=1;i<=n;i++){
q.push({a[i],b[i],a[i]/b[i]});
}
for(int i=1;i<=m;i++){
node t=q.top();q.pop();
if(t.c<i-1) return false;
if(t.c>=m) return true;
q.push({t.a+x,t.b,(t.a+x)/t.b});
}
return true;
}
int Sheryang()
{
n=read,m=read;
for(int i=1;i<=n;i++){
a[i]=read;
}
for(int i=1;i<=n;i++){
b[i]=read;
}
ll l=0,r=1e14,ans=-1;
while(l<=r){
ll mid=(l+r)/2;
if(judge(mid)){
ans=mid;
r=mid-1;
}else{
l=mid+1;
}
}
printf("%lld\n",ans);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define Sheryang main
const int maxn=1e6+7;
typedef long long ll;
const int mod=1e9+7;
void Smax(int &a,int b){if(a<b) a=b;}
void Smin(int &a,int b){if(a>b) a=b;}
///#define getchar()(p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
///char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
#define IO cin.tie(0),ios::sync_with_stdio(false);
#define pi acos(-1)
#define PII pair<ll,ll>
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
/** keep hungry and keep calm! **/
ll a[maxn],b[maxn],cur[maxn];
ll n,m;
vector<int>lis[maxn];
bool judge(ll x){
for(int i=0;i<m;i++){
lis[i].clear();
}
for(int i=0;i<n;i++){
ll t=a[i]/b[i]+1;
cur[i]=a[i]%b[i];
if(t<m){
lis[t].push_back(i);
}
}
int now=1;
for(int i=0;i<m;i++){
while(now<m && lis[now].empty()){
now++;
}
if(now==m) return true;
if(now<=i) return false;
int t=lis[now].back();
if(cur[t]+x<b[t]){
cur[t]+=x;
continue;
}
lis[now].pop_back();
ll nt=(cur[t]+x)/b[t];
cur[t]+=x;cur[t]%=b[t];
if(nt+now<m){
lis[now+nt].push_back(t);
}
}
return true;
}
int Sheryang()
{
n=read,m=read;
for(int i=0;i<n;i++){
a[i]=read;
}
for(int i=0;i<n;i++){
b[i]=read;
}
ll l=0,r=1e14,ans=-1;
while(l<=r){
ll mid=(l+r)/2;
if(judge(mid)){
ans=mid;
r=mid-1;
}else{
l=mid+1;
}
}
printf("%lld\n",ans);
return 0;
}