20240418
This commit is contained in:
107
ACMOJ-2148.cpp
Normal file
107
ACMOJ-2148.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
typedef long double LDB;
|
||||
const int kMaxN = 1e5 + 10;
|
||||
int N, S;
|
||||
LDB A[kMaxN], B[kMaxN], R[kMaxN];
|
||||
struct NodeType {
|
||||
int rawid;
|
||||
LDB a, b, r, f;
|
||||
};
|
||||
NodeType nodes[kMaxN];
|
||||
inline LDB GetX(const NodeType &node) {
|
||||
return node.f * node.r / (node.a * node.r + node.b);
|
||||
}
|
||||
inline LDB GetY(const NodeType &node) {
|
||||
return node.f / (node.a * node.r + node.b);
|
||||
}
|
||||
bool CmpX(const NodeType &na, const NodeType &nb) {
|
||||
return GetX(na) < GetX(nb);
|
||||
}
|
||||
bool CmpId(const NodeType &na, const NodeType &nb) {
|
||||
return na.rawid < nb.rawid;
|
||||
}
|
||||
bool CmpK(const NodeType &na, const NodeType &nb) {
|
||||
return -na.a / na.b > -nb.a / nb.b;
|
||||
}
|
||||
int Q[kMaxN], QL, QR;
|
||||
typedef bool (*CmpType)(const NodeType &, const NodeType &);
|
||||
void MergeSort(NodeType *beg, NodeType *end, CmpType cmp) {
|
||||
if (end - beg <= 1) return;
|
||||
size_t len = end - beg;
|
||||
NodeType *mid = beg + (len >> 1);
|
||||
MergeSort(beg, mid, cmp);
|
||||
MergeSort(mid, end, cmp);
|
||||
NodeType *tmp = new NodeType[len];
|
||||
NodeType *cur_tmp = tmp, *cur_L = beg, *cur_R = mid;
|
||||
while ((cur_L < mid) && (cur_R < end)) {
|
||||
if (cmp(*cur_L, *cur_R))
|
||||
*(cur_tmp++) = *(cur_L++);
|
||||
else
|
||||
*(cur_tmp++) = *(cur_R++);
|
||||
}
|
||||
while (cur_L < mid) *(cur_tmp++) = *(cur_L++);
|
||||
while (cur_R < end) *(cur_tmp++) = *(cur_R++);
|
||||
cur_tmp = tmp;
|
||||
NodeType *cur_dst = beg;
|
||||
while (cur_dst < end) *(cur_dst++) = *(cur_tmp++);
|
||||
delete[] tmp;
|
||||
}
|
||||
void CDQ(int L, int R) {
|
||||
if (L == R) return;
|
||||
int M = (L + R) >> 1;
|
||||
CDQ(L, M);
|
||||
MergeSort(nodes + L, nodes + M + 1, CmpX);
|
||||
MergeSort(nodes + M + 1, nodes + R + 1, CmpK);
|
||||
Q[QL = QR = 0] = L;
|
||||
for (int i = L + 1; i <= M; i++) {
|
||||
while (QR - QL + 1 >= 2 &&
|
||||
(GetX(nodes[Q[QR]]) - GetX(nodes[Q[QR - 1]])) *
|
||||
(GetY(nodes[i]) - GetY(nodes[Q[QR - 1]])) -
|
||||
(GetY(nodes[Q[QR]]) - GetY(nodes[Q[QR - 1]])) *
|
||||
(GetX(nodes[i]) - GetX(nodes[Q[QR - 1]])) >=
|
||||
0)
|
||||
QR--;
|
||||
Q[++QR] = i;
|
||||
}
|
||||
LDB base = 0;
|
||||
for (int i = L; i <= M; i++) base = max(base, nodes[i].f);
|
||||
for (int i = M + 1; i <= R; i++) {
|
||||
while (QR - QL + 1 >= 2 &&
|
||||
(GetY(nodes[Q[QL + 1]]) - GetY(nodes[Q[QL]])) /
|
||||
(GetX(nodes[Q[QL + 1]]) - GetX(nodes[Q[QL]])) >=
|
||||
-nodes[i].a / nodes[i].b)
|
||||
QL++;
|
||||
nodes[i].f = max(nodes[i].f, base);
|
||||
nodes[i].f = max(nodes[i].f, nodes[i].a * GetX(nodes[Q[QL]]) +
|
||||
nodes[i].b * GetY(nodes[Q[QL]]));
|
||||
}
|
||||
MergeSort(nodes + M + 1, nodes + R + 1, CmpId);
|
||||
CDQ(M + 1, R);
|
||||
}
|
||||
int main() {
|
||||
#ifdef local
|
||||
freopen("pro.in", "r", stdin);
|
||||
#endif
|
||||
scanf("%d%d", &N, &S);
|
||||
for (int i = 1; i <= N; i++) {
|
||||
scanf("%Lf%Lf%Lf", &A[i], &B[i], &R[i]);
|
||||
nodes[i].rawid = i;
|
||||
nodes[i].a = A[i];
|
||||
nodes[i].b = B[i];
|
||||
nodes[i].r = R[i];
|
||||
}
|
||||
nodes[1].f = S;
|
||||
CDQ(1, N);
|
||||
// for (int i = 1; i <= N; i++)
|
||||
// printf("f(%d)=%.3Lf\n", nodes[i].rawid, nodes[i].f);
|
||||
for (int i = 1; i <= N; i++)
|
||||
if (nodes[i].rawid == N) {
|
||||
printf("%.3Lf\n", nodes[i].f);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user