이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "bits/stdc++.h"
#include "closing.h"
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define ar array
using namespace std;
typedef long long ll;
using pi = pair<int, int>;
using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pi>;
const ll INF = 4e18;
struct SegTree {
vector<ll> t;
int n;
void build(int _n) {
n = _n;
t.resize(n * 2);
}
void upd(int i, ll x) {
for (t[i += n] += x; i > 1; i >>= 1) t[i >> 1] = t[i] + t[i ^ 1];
}
ll get(int l, int r) {
ll s = 0;
for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
if (l & 1) s += t[l++];
if (r & 1) s += t[--r];
}
return s;
}
};
pair<vl, vi> BuildC(int n, int x, vector<vpi> g) {
vector<ll> c(n, INF);
vector<int> p(n, -1);
c[x] = 0;
queue<int> q;
q.push(x);
while (!q.empty()) {
int v = q.front();
q.pop();
for (auto [u, w]: g[v]) {
if (c[u] > w + c[v]) {
c[u] = w + c[v];
p[u] = v;
q.push(u);
}
}
}
return {c, p};
}
int max_score(int n, int x, int y, ll k, vi U, vi V, vi W) {
k *= 2;
int ans = 2;
vector<vpi> g(n);
rep(i, U.size()) {
int u = U[i];
int v = V[i];
int w = W[i];
w *= 2;
g[u].emplace_back(v, w);
g[v].emplace_back(u, w);
}
auto [cx, px] = BuildC(n, x, g);
auto [cy, py] = BuildC(n, y, g);
{
auto sx = cx, sy = cy;
sort(all(sx));
sort(all(sy));
ll sum = accumulate(all(sy), 0ll);
int j = n;
for (int i = 0; i <= n; ++i) {
if (i) sum += sx[i - 1];
while (j > 0 && sum > k) {
j--;
sum -= sy[j];
}
if (sum > k) break;
ans = max(ans, i + j);
}
}
vector<int> mids;
{
ll mx = INF;
rep(i, n) {
ll val = max(cx[i], cy[i]);
if (val < mx) {
mids.clear();
mx = val;
}
if (val == mx) mids.emplace_back(i);
}
}
for (auto mid: mids) {
vector<int> state(n);
ll use = max(cx[mid], cy[mid]);
state[mid] = 2;
for (int vx = px[mid]; vx != -1; vx = px[vx]) {
state[vx] = 1;
use += cx[vx];
}
for (int vy = py[mid]; vy != -1; vy = py[vy]) {
state[vy] = 1;
use += cy[vy];
}
if (use > k) continue;
int score_default = accumulate(all(state), 0);
ans = max(ans, score_default);
vector<ll> xx;
xx.push_back(-INF);
xx.push_back(INF);
vector<ll> diff(n), mx(n), mn(n);
rep(i, n) {
diff[i] = abs(cx[i] - cy[i]);
xx.push_back(diff[i]);
mn[i] = min(cx[i], cy[i]);
mx[i] = max(cx[i], cy[i]);
xx.push_back(mx[i] / 2);
}
sort(all(xx));
xx.resize(unique(all(xx)) - xx.begin());
auto GetInd = [&](ll x) {
int i = lower_bound(all(xx), x) - xx.begin();
return i;
};
int sz = xx.size();
SegTree st1, st2, ct1, ct2;
st1.build(sz);
st2.build(sz);
ct1.build(sz);
ct2.build(sz);
vi ord2;
vi ord1;
rep(i, n) {
if (state[i] == 2) continue;
if (state[i] == 1) {
st1.upd(GetInd(diff[i]), diff[i]);
ct1.upd(GetInd(diff[i]), 1);
continue;
}
ord2.push_back(i);
ord1.push_back(i);
}
sort(all(ord1),
[&](const int &i, const int &j) { return mn[i] < mn[j]; });
sort(all(ord2),
[&](const int &i, const int &j) { return diff[i] < diff[j]; });
vector<bool> ok(n);
auto FindNext = [&](int l) {
int L = l - 1;
int R = sz;
while (R - L > 1) {
int mid = (L + R) / 2;
if (ct1.get(l, mid + 1)) {
R = mid;
} else {
L = mid;
}
}
return R;
};
auto FindLast = [&](int l) {
int L = -1;
int R = l + 1;
while (R - L > 1) {
int mid = (L + R) / 2;
if (ct1.get(mid, l + 1)) {
L = mid;
} else {
R = mid;
}
}
return L;
};
auto FindNext2 = [&](int l) {
int L = l - 1;
int R = sz;
while (R - L > 1) {
int mid = (L + R) / 2;
if (ct2.get(l, mid + 1)) {
R = mid;
} else {
L = mid;
}
}
return R;
};
auto Check = [&]() {
if (use > k) return;
int l = -1;
int r = sz;
while (r - l > 1) {
int mid = (l + r) / 2;
ll s = st1.get(0, mid + 1) + st2.get(0, mid + 1);
if (s + use <= k) {
l = mid;
} else {
r = mid;
}
}
int SCORE = score_default + ct1.get(0, r) + ct2.get(0, r) * 2;
if (r == sz) {
ans = max(ans, SCORE);
return;
}
ll HAVE = k - use - st1.get(0, r) - st2.get(0, r);
int CNT1 = ct1.get(r, r + 1);
int CNT2 = ct2.get(r, r + 1);
int nxt = FindNext(r + 1);
int last = FindLast(l);
int to2 = CNT2 ? r : FindNext2(r);
{
int CNT22 = ct2.get(to2, to2 + 1);
if (last != -1 && to2 != sz) {
int score = SCORE;
int cnt2 = CNT22;
ll have = HAVE;
score--;
have += xx[last];
ll t2 = min(1ll * cnt2, have / (2 * xx[to2]));
score += t2;
ans = max(ans, score);
}
if (to2 != sz) {
ll have = HAVE;
int cnt2 = CNT22;
int score = SCORE;
ll t2 = min(1ll * cnt2, have / (2 * xx[to2]));
score += t2 * 2;
ans = max(ans, score);
}
}
{
ll have = HAVE;
int cnt2 = CNT2;
int score = SCORE;
int cnt1 = CNT1;
if (cnt2) {
ll t2 = min(1ll * cnt2, have / (2 * xx[r]));
cnt2 -= t2;
have -= t2 * xx[r] * 2;
score += t2 * 2;
}
if (cnt1) {
ll t1 = min(1ll * cnt1, have / xx[r]);
cnt1 -= t1;
have -= t1 * xx[r];
score += t1;
}
if (nxt != sz && xx[nxt] <= have) {
have -= xx[nxt];
score++;
}
ans = max(ans, score);
}
};
int uk2 = 0;
auto Check2 = [&](ll value) {
while (uk2 < ord2.size() && diff[ord2[uk2]] <= value) {
int i = ord2[uk2++];
if (state[i] == 0) {
ok[i] = true;
st2.upd(GetInd(mx[i] / 2), mx[i]);
ct2.upd(GetInd(mx[i] / 2), 1);
}
}
Check();
};
for (auto &i: ord1) {
Check2(mn[i] - 1);
state[i] = 1;
use += mn[i];
if (use > k) break;
score_default++;
if (ok[i]) {
st2.upd(GetInd(mx[i] / 2), -mx[i]);
ct2.upd(GetInd(mx[i] / 2), -1);
}
st1.upd(GetInd(diff[i]), diff[i]);
ct1.upd(GetInd(diff[i]), 1);
Check();
}
Check2(INF);
}
return ans;
}
컴파일 시 표준 에러 (stderr) 메시지
closing.cpp: In function 'int max_score(int, int, int, ll, vi, vi, vi)':
closing.cpp:4:36: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
4 | #define rep(i, n) for(int i = 0; i < (n); ++i)
| ^
closing.cpp:67:5: note: in expansion of macro 'rep'
67 | rep(i, U.size()) {
| ^~~
closing.cpp: In lambda function:
closing.cpp:274:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
274 | while (uk2 < ord2.size() && diff[ord2[uk2]] <= value) {
| ~~~~^~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |