对于第i天,我们要给它腾出位置,为了使温度最高,要删除的时前面温度最低的。
对于一个新加入的温度,如果它比之前的温度都要高。直接加入即可。
如果它不是最高温,我们把它与前一个温度混合,直到混合后的温度是最高温。
原因如下:
对于之后加入的温度,我们要么踢掉一部分之前的混合液t2,把它与当前的温度t1混合,要么把它与t1与之前的混合液t2混合的温度t3混合,再踢掉一部分t3以腾出空间(这样可以得到t1<t2<t3)
那么我们显然选择的是t3(温度更高),所以对于这种情况我们要把它与前面的混合
这个我们只要维护一个单调递增的单调队列来维护温度就行了。
代码
#include<bits/stdc++.h> using namespace std; #define N 500010 int st,ed; struct data { double t,v; } datas[N],q[N]; data merge(data a,data b) { data c; c.v=a.v+b.v; c.t=(a.t*a.v+b.t*b.v)/c.v; return c; } signed main() { int n,l; cin>>n>>l; for(int i=1; i<=n; i++) { scanf("%lf%lf",&datas[i].t,&datas[i].v); } double sum=0,tot=0; q[st=ed=1]=datas[1],sum=datas[1].v,tot=datas[1].t*datas[1].v; printf("%lf\n",datas[1].t); for(int i=2; i<=n; i++) { q[++ed]=datas[i],tot+=datas[i].v*datas[i].t,sum+=datas[i].v; while(ed>st&&sum>l) { if(sum-q[st].v>=l) { tot-=q[st].v*q[st].t; sum-=q[st].v; st++; } else { q[st].v-=sum-l; tot-=(sum-l)*q[st].t; sum-=sum-l; } } while(ed>st) { if(q[ed].t>=q[ed-1].t) break; data d=merge(q[ed],q[ed-1]); q[--ed]=d; } printf("%.10f\n",tot/sum); } }