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;
}