题目链接:https://nanti.jisuanke.com/t/41306
题目大意:有n个人,每个人到达的时间是t[i],每个人都得洗衣服,手洗的时间是y,机洗的时间是x,大家可以一起手洗但是同一时间只能有一个人机洗,问最后一个人洗完的最早时间
题目思路:首先可以注意到一点,如果每个人都是手洗的话,那么每个人停止的时间就是t[i]+y。假设我们已经知道了那个最早时间,那么假如有一个家伙手洗来不及了,那他想要完成任务唯一的可能就是去机洗,如果连这家伙都来不及了,那他后面的家伙就更来不及了,所以应该是,前面一部分人都在手洗,后面一部分都在机洗。假设一个人开始机洗,那么他的贡献就是从这一刻开始,后面的家伙都机洗,也就是就是从这家伙开始,后面的都能连着用洗衣机的情况的最大值求max。所以一个家伙对答案的贡献有两种可能,一种是t[i]+y,另一种是t[i]+(n-i+1)*x,肯定大家都想往小了走,所以这是一个分段函数,先递增然后保持不变,而且可以发现,转折点是y/(n-i+1),那么越靠后的人,斜率越小,转折点越靠后,所以只要一个人洗衣服他后面的家伙肯定都取得是洗衣服的情况,自动保证了这家伙洗衣服以后后面的人都在洗衣服,那么就把这些分段函数全插进去,然后在每个x求最大值就行了。
以下是代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
const int MAXN = 1e6+5;
int n,y;
int t[MAXN];
struct line{
db k,b;
int l,r,flag;
}a[MAXN<<1],k;
inline int get_id(int l,int r){return (l+r)|(l!=r);}
inline db calc(line a,int pos){return a.k*pos+a.b;}
void build(int l,int r){
int rt=get_id(l,r);
a[rt].k=a[rt].b=a[rt].l=a[rt].r=a[rt].flag=0;
if(l==r)return;
int mid=(l+r)>>1;
build(l,mid);build(mid+1,r);
}
void update(int l,int r,line k){
int rt=get_id(l,r);
if(k.l<=l&&r<=k.r){
if(!a[rt].flag)a[rt]=k,a[rt].flag=1;
else if(calc(k,l)>=calc(a[rt],l)&&calc(k,r)>=calc(a[rt],r))a[rt]=k;
else if(calc(k,l)>calc(a[rt],l)||calc(k,r)>calc(a[rt],r)){
int mid=(l+r)>>1;
if(calc(k,mid)>calc(a[rt],mid)){
swap(k,a[rt]);
}
if(calc(k,l)>calc(a[rt],l))update(l,mid,k);
else update(mid+1,r,k);
}
}
else{
if(l==r)return;
int mid=(l+r)>>1;
if(k.l<=mid)update(l,mid,k);
if(mid<k.r)update(mid+1,r,k);
}
}
ll query(int l,int r,int x){
int rt=get_id(l,r);
if(l==r)return calc(a[rt],x);
else {
int mid=(l+r)>>1;
ll ans=calc(a[rt],x);
if(x<=mid)return max(ans,query(l,mid,x));
else return max(ans,query(mid+1,r,x));
}
}
int main(){
while(~scanf("%d%d",&n,&y)){
rep(i,1,n)scanf("%d",&t[i]);
sort(t+1,t+n+1);
build(1,y);
rep(i,1,n){
int pos=y/(n-i+1);
k.l=1,k.r=pos,k.flag=1,k.k=n-i+1,k.b=t[i];
update(1,y,k);
k.l=pos+1,k.r=y,k.flag=1,k.k=0,k.b=t[i]+y;
update(1,y,k);
}
rep(i,1,y){
printf("%lld%c",query(1,y,i),i==y?'\n':' ');
}
}
return 0;
}