QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#629846 | #9440. Train Seats | zqs | RE | 0ms | 18032kb | C++14 | 3.0kb | 2024-10-11 15:10:41 | 2024-10-11 15:10:42 |
Judging History
answer
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cassert>
typedef long long ll;
const ll INF = 1000000000000000ll;
int a[200005], n, m, stk[200005], top; ll suf[200005];
struct Segment_tree {
struct node {int l, r, c1, c2; ll v, s1, s2;} tr[4000005];
void build(int p, int l, int r) {
tr[p].l = l, tr[p].r = r;
if (l < r) build(p << 1, l, l + r >> 1), build(p << 1 | 1, (l + r >> 1) + 1, r);
}
inline void pushup(int p) {
node &ls = tr[p << 1], &rs = tr[p << 1 | 1];
tr[p].v = ls.v + rs.v + ls.c1 * rs.s2 + ls.c2 * rs.s1;
tr[p].c1 = ls.c1 + rs.c1, tr[p].c2 = ls.c2 + rs.c2;
tr[p].s1 = ls.s1 + rs.s1, tr[p].s2 = ls.s2 + rs.s2;
}
void update(int x, int tp, int c, int s) {
int p = 1;
while (tr[p].l < tr[p].r) {
int mid = tr[p].l + tr[p].r >> 1;
x <= mid ? p <<= 1 : p = p << 1 | 1;
}
if (tp == 1) tr[p].c1 += c, tr[p].s1 += s; else tr[p].c2 += c, tr[p].s2 += s;
tr[p].v = tr[p].c1 * tr[p].s2;
while (p >>= 1) pushup(p);
}
} sgt;
struct node {
int x, y;
inline bool operator < (const node &rhs) const {return 1ll * x * rhs.y < 1ll * y * rhs.x;}
inline bool operator == (const node &rhs) const {return 1ll * x * rhs.y == 1ll * y * rhs.x;}
} lis[2000005];
struct upd {int c, s;};
std::vector<upd> cg2[200005], cg1[200005];
ll ans;
void add(int tp, int c, int s) {
node tmp = node{abs(s), abs(c)};
int pos = std::lower_bound(lis + 1, lis + m + 1, tmp) - lis;
assert(lis[pos]==tmp);
sgt.update(pos, tp, c, s);
}
int main() {
scanf("%d", &n); scanf("%d", a + n + 1), ++ a[n + 1];
for (int i = 1; i <= n; ++ i) scanf("%d", a + i);
std::sort(a + 1, a + n + 1);
for (int i = n; i; -- i) suf[i] = suf[i + 1] + 1ll * (a[i + 1] - a[i]) * (n - i + 1);
for (int i = 1; i <= n; ++ i) {//move from i to i + 1
while (top) {
int x = stk[top], y = stk[top - 1];
if (1ll * (a[i] - a[x]) * (x - y) <= 1ll * (a[x] - a[y]) * (i - x))
cg1[i].push_back(upd{a[y] - a[x], y - x}), -- top;
else break;
}
cg1[i].push_back(upd{a[i] - a[stk[top]], i - stk[top]}), stk[++ top] = i;
}
stk[top = 0] = n + 1;
for (int i = n; i; -- i) {
while (top) {
int x = stk[top], y = stk[top - 1];//[i,x),[x,y)
if (1ll * (a[x] - a[i]) * (y - x) <= 1ll * (a[y] - a[x]) * (x - i))
cg2[i].push_back(upd{a[y] - a[x], y - x}), -- top;
else break;
}
cg2[i].push_back(upd{a[i] - a[stk[top]], i - stk[top]}), stk[++ top] = i;
}
for (int i = 1; i <= n; ++ i) {
for (upd j : cg1[i]) lis[++ m] = node{j.s, j.c};
for (upd j : cg2[i]) lis[++ m] = node{-j.s, -j.c};
}
std::sort(lis + 1, lis + m + 1);
sgt.build(1, 1, m = std::unique(lis + 1, lis + m + 1) - lis - 1);
while (top) add(2, a[stk[top - 1]] - a[stk[top]], stk[top - 1] - stk[top]), -- top;
ll now = 0;
for (int i = 1; i <= n; ++ i) {
for (upd j : cg1[i - 1]) add(1, j.c, j.s);
for (upd j : cg2[i]) add(2, j.c, j.s);
ans = std::max(ans, now + suf[i + 1] + 1ll * (a[i + 1] - a[i - 1]) * n + sgt.tr[1].v);
now += 1ll * (a[i] - a[i - 1]) * i;
}
printf("%lld", ans);
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 18032kb
input:
3 10 3 7 10
output:
28
result:
ok "28"
Test #2:
score: -100
Runtime Error
input:
5 20 3 10 11 14 17