1 条题解
-
0
自动搬运
来自洛谷,原作者为

251Sec
祈祷着今后的你的人生,永远都有幸福的“魔法”相伴。搬运于
2025-08-24 22:20:13,当前版本为作者最后更新于2025-06-04 16:26:16,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
先考虑只有 deque 的情况,注意到若存在 这样的结构,那么先手若取了 后手一定取 ,然后先手一定取 ,于是把它们合成一个数 。于是所有 deque 都是单谷的,此时最优策略就是取最大的可取的数。然后有两个栈的情况,只需要把它们拼起来并在中间加上一个 即可。
所以为什么大家都在写链表?
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll inf = 1e13; int n; ll a[1000005]; vector<ll> Comp(vector<ll> a) { vector<ll> b; for (ll x : a) { b.push_back(x); while (b.size() >= 3) { ll x = b[b.size() - 1], y = b[b.size() - 2], z = b[b.size() - 3]; if (y >= x && y >= z) { for (int i = 0; i < 3; i++) b.pop_back(); b.push_back(x + z - y); } else break; } } return b; } vector<ll> f; void Add(vector<ll> a) { int i = 0, j = a.size() - 1; while (i <= j) { if (a[i] >= a[j]) f.push_back(a[i++]); else f.push_back(a[j--]); } } ll s; int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%lld", a + i), s += a[i]; for (int i = 1, j; i <= n; ) { if (a[i]) { i++; continue; } j = i + 1; while (j <= n && a[j]) j++; if (j <= n) { vector<ll> b; for (int p = i + 1; p < j; p++) b.push_back(a[p]); Add(Comp(b)); } i = j; } vector<ll> t; for (int i = n; i; i--) { if (!a[i]) break; t.push_back(a[i]); } reverse(t.begin(), t.end()); t.push_back(-inf); for (int i = 1; i <= n; i++) { if (!a[i]) break; t.push_back(a[i]); } Add(Comp(t)); sort(f.begin(), f.end(), greater<ll>()); ll res = 0; for (int i = 0; i < f.size(); i++) res += ((i & 1) ? -1 : 1) * f[i]; if (res < 0) res += inf; else res -= inf; printf("%lld %lld\n", (s + res) / 2, (s - res) / 2); return 0; }
- 1
信息
- ID
- 5398
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者