QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#55057 | #1269. New Equipments | YaoBIG | AC ✓ | 407ms | 12588kb | C++17 | 4.5kb | 2022-10-12 07:22:47 | 2022-10-12 07:22:49 |
Judging History
answer
#include "bits/stdc++.h"
#define rep(i, a, n) for (auto i = a; i <= (n); i++)
#define revrep(i, a, n) for (auto i = n; i >= (a); i++)
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a).size()
template<class T> bool chmin(T &a, T b) { if (a > b) { a = b; return 1; } else return 0; }
template<class T> bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } else return 0; }
using namespace std;
template<class A, class B> string to_string(pair<A, B> p);
template<class A> string to_string(A v) {
bool first = 1;
string res = "{";
for (auto x: v) {
if (!first) res += ", ";
first = 0;
res += to_string(x);
}
res += "}";
return res;
}
template<class A, class B> string to_string(pair<A, B> p) {
return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
void debug_out() { cerr << endl; }
template<class H, class... T> void debug_out(H h, T... t) {
cerr << " " << to_string(h);
debug_out(t...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
template<class Cap, class Cost, Cap Cap_MAX = numeric_limits<Cap>::max(), Cost Cost_MAX = numeric_limits<Cost>::max() / 4>
struct SuccessiveShortestPath {
int n;
struct E { int v; Cap a; Cost w; };
vector<E> e;
vector<vi> g;
vector<Cost> h;
SuccessiveShortestPath(int n): n(n), g(n), h(n) {}
void add(int u, int v, Cap c, Cost w) {
g[u].push_back(sz(e)); e.push_back({v, c, w});
g[v].push_back(sz(e)); e.push_back({u, 0, -w});
}
vector<Cost> mincostflow(int src, int sink, Cap mx_flow = Cap_MAX) {
Cost cost = 0;
Cap flow = 0;
vector<Cost> res;
while(mx_flow) {
priority_queue<pair<Cost, int> > pq;
vector<Cost> dis(n, Cost_MAX);
dis[src] = 0; pq.emplace(0, src);
vi pre(n, -1), mark(n, 0);
while (sz(pq)) {
auto [d, now] = pq.top(); pq.pop();
// Using mark[] is safer than compare -d and dis[now] when the cost is float type.
if (mark[now]) continue;
mark[now] = 1;
for (auto i: g[now]) {
auto [v, c, w] = e[i];
Cost off = dis[now] + w + h[now] - h[v];
if (c > 0 && dis[v] > off) {
dis[v] = off;
pq.emplace(-dis[v], v);
pre[v] = i;
}
}
}
if (pre[sink] == -1) break;
rep(i, 0, n - 1) if (dis[i] != Cost_MAX) h[i] += dis[i];
Cap aug = mx_flow;
for(int i = pre[sink]; ~i; i = pre[e[i ^ 1].v]) aug = min(aug, e[i].a);
for(int i = pre[sink]; ~i; i = pre[e[i ^ 1].v]) e[i].a -= aug, e[i ^ 1].a += aug;
mx_flow -= aug;
flow += aug;
cost += aug * h[sink];
res.push_back(cost);
}
return res;
}
// Calculate distance on residual graph
Cost cal_dis(int st, int ed) {
priority_queue<pair<Cost, int> > pq;
vector<Cost> dis(n, Cost_MAX);
dis[st] = 0; pq.emplace(0, st);
vi mark(n, 0);
while (sz(pq)) {
auto [d, now] = pq.top(); pq.pop();
if (mark[now]) continue; // again, using mark is safe when C = double.
mark[now] = 1;
for (auto i: g[now]) {
auto [v, c, w] = e[i];
Cost off = dis[now] + w + h[now] - h[v];
if (c > 0 && dis[v] > off) dis[v] = off, pq.emplace(-dis[v], v);
}
}
return dis[ed] + h[ed] - h[st];
}
};
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int cas; cin >> cas; while (cas--) {
int n, m; cin >> n >> m;
vector<ll> as(n), bs(n), cs(n);
rep(i, 0, n - 1) {
cin >> as[i] >> bs[i] >> cs[i];
}
vector<ll> nums;
rep(i, 0, n - 1) {
ll a = as[i], b = bs[i];
ll x0 = -b / (a * 2);
chmin(x0, 1ll * m);
chmax(x0, 1ll);
vector<ll> pos;
rep(j, 0, n + 5) if (x0 - j >= 1) pos.push_back(x0 - j);
rep(j, 0, n + 5) if (x0 + j <= m) pos.push_back(x0 + j);
sort(all(pos), [&](ll i, ll j) { return a * i * i + b * i < a * j * j + b * j; });
pos.erase(unique(all(pos)), pos.end());
if (sz(pos) > n) pos.resize(n);
nums.insert(nums.end(), all(pos));
}
sort(all(nums));
nums.erase(unique(all(nums)), nums.end());
int tot = sz(nums);
int N = n + tot;
int src = N++, sink = N++;
SuccessiveShortestPath<int, ll> mcmf(N);
rep(i, 0, n - 1) mcmf.add(src, i, 1, 0);
rep(i, 0, tot - 1) mcmf.add(i + n, sink, 1, 0);
const ll off = 2e16;
rep(i, 0, n - 1) {
ll a = as[i], b = bs[i], c = cs[i];
rep(j, 0, tot - 1){
ll x = nums[j];
mcmf.add(i, n + j, 1, a * x * x + b * x + c + off);
}
}
auto res = mcmf.mincostflow(src, sink);
rep(i, 0, n - 1) {
ll x = res[i] - off * (i + 1);
printf("%lld%c", x, " \n"[i == n - 1]);
}
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3588kb
input:
1 3 5 2 3 10 2 -3 10 1 -1 4
output:
4 15 37
result:
ok single line: '4 15 37'
Test #2:
score: 0
Accepted
time: 407ms
memory: 12588kb
input:
10 50 50 2 -16 79 8 -21 54 8 -1 3 1 -7 47 5 -20 89 1 -2 47 2 -10 26 10 31 28 2 -16 37 6 -16 44 2 -8 100 3 -26 65 3 -6 91 10 -33 56 2 -7 22 2 -12 74 1 -3 7 7 -30 51 1 -4 8 1 -10 62 2 -5 5 1 -3 38 7 -32 57 4 -24 65 1 -8 97 7 -28 71 5 -13 71 2 -14 49 6 -33 100 2 7 69 8 -22 38 5 -23 88 7 20 57 7 -11 83 ...
output:
2 4 9 14 24 40 72 117 170 239 327 445 592 771 972 1202 1467 1772 2117 2506 2954 3461 4035 4690 5415 6223 7137 8145 9272 10499 11858 13366 15003 16798 18736 20810 23058 25517 28172 31062 34194 37566 41209 45136 49371 53924 58847 64143 69813 75884 4 9 17 25 33 43 57 78 107 146 194 266 356 461 590 744 ...
result:
ok 10 lines