AT2402 [ARC072D] Dam
显然体积不变,使热量最大。
单调队列维护热量段,满足单调递增。
每次放水就取出队头。
加水就维护单调队列,融合一下。
时间复杂度 。
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
#define ha putchar(' ')
#define he putchar('\n')
namespace Fread
{
const int SIZE = 1 << 15;
char buf[SIZE], *S, *T;
inline char getchar()
{
if (S == T)
{
T = (S = buf) + fread(buf, 1, SIZE, stdin);
if (S == T)
return '\n';
}
return *S++;
}
}
#ifdef ONLINE_JUDGE
#define getchar Fread::getchar
#endif
inline int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x * f;
}
const int _ = 5e5 + 10;
int n, L;
long double t[_], v[_];
struct Node
{
int v; long double t;
} q[_];
signed main()
{
n = read(), L = read();
for(int i = 1; i <= n; ++i)
t[i] = read(), v[i] = read();
int l = 1, r = 0;
int cv = 0; long double ans = 0.0000000000;
for(int i = 1; i <= n; ++i)
{
while(cv + v[i] > L)
{
int dl = min(q[l].v, cv - (L - (int)v[i]));
q[l].v -= dl, cv -= dl, ans -= q[l].t * dl;
if(!q[l].v) ++l;
}
cv = L, ans += t[i] * v[i];
++r, q[r].t = t[i], q[r].v = v[i];
while(l < r && q[r - 1].t > q[r].t)
{
q[r - 1].t = ((q[r - 1].v * q[r - 1].t) + (q[r].v * q[r].t)) / (q[r - 1].v + q[r].v);
q[r - 1].v += q[r].v;
r--;
}
printf("%.7Lf\n", (long double)ans / L);
}
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121940