QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#731684 | #9569. Subway | hos_lyric | RE | 0ms | 4104kb | C++14 | 5.6kb | 2024-11-10 10:28:54 | 2024-11-10 10:28:54 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
template <class Func> struct MinLiChaoTree {
using TX = typename Func::TX;
using TY = typename Func::TY;
struct Node {
int l, r;
Func f;
};
vector<Node> nodes;
/*const*/ TX XL, XR;
int rt;
MinLiChaoTree() : XL(0), XR(0), rt(-1) {}
// [XL, XR)
MinLiChaoTree(TX XL_, TX XR_) : XL(XL_), XR(XR_), rt(-1) {}
bool empty() const {
return (!~rt);
}
// Add f to the whole [XL, XR).
void add(Func f) {
int *u = &rt;
for (TX xL = XL, xR = XR; ; ) {
if (!~*u) { *u = nodes.size(); nodes.push_back({-1, -1, f}); return; }
const TX xMid = xL + (xR - xL) / 2;
if (f(xMid) < nodes[*u].f(xMid)) swap(nodes[*u].f, f);
if (xL + 1 == xR) return;
if (f(xL) < nodes[*u].f(xL)) {
u = &nodes[*u].l; xR = xMid;
} else if (f(xR - 1) < nodes[*u].f(xR - 1)) {
u = &nodes[*u].r; xL = xMid;
} else {
return;
}
}
}
// Get min at x.
TY operator()(TX x) const {
assert(XL <= x); assert(x < XR);
assert(!empty());
int u = rt;
TY minY = nodes[u].f(x);
for (TX xL = XL, xR = XR; ; ) {
const TX xMid = xL + (xR - xL) / 2;
if (x < xMid) {
u = nodes[u].l; xR = xMid;
} else {
u = nodes[u].r; xL = xMid;
}
if (!~u) break;
const TY y = nodes[u].f(x);
if (y < minY) minY = y;
}
return minY;
}
}; // MinLiChaoTree
// y = p x + q
struct Line {
using TX = long long;
using TY = long long;
long long p, q;
Line() {}
Line(long long p_, long long q_) : p(p_), q(q_) {}
TY operator()(TX x) const {
return p * x + q;
}
};
constexpr Int INF = 4001001001001001001LL;
int N, K;
vector<Int> A, B;
vector<int> P;
vector<vector<int>> X;
vector<vector<Int>> W;
int main() {
for (; ~scanf("%d%d", &N, &K); ) {
A.resize(K); for (int k = 0; k < K; ++k) scanf("%lld", &A[k]);
B.resize(K); for (int k = 0; k < K; ++k) scanf("%lld", &B[k]);
P.resize(K);
X.resize(K);
W.resize(K);
for (int k = 0; k < K; ++k) {
scanf("%d", &P[k]);
--P[k];
X[k].resize(P[k] + 1);
W[k].resize(P[k]);
for (int p = 0; ; ++p) {
scanf("%d", &X[k][p]);
--X[k][p];
if (p == P[k]) break;
scanf("%lld", &W[k][p]);
}
}
auto minmaxA = minmax_element(A.begin(), A.end());
vector<MinLiChaoTree<Line>> lcts(N);
for (int u = 0; u < N; ++u) lcts[u] = MinLiChaoTree<Line>(*minmaxA.first, *minmaxA.second + 1);
vector<vector<pair<Int, pair<int, int>>>> akpss(N);
for (int k = 0; k < K; ++k) for (int p = 0; p <= P[k]; ++p) akpss[X[k][p]].emplace_back(A[k], make_pair(k, p));
for (int u = 0; u < N; ++u) sort(akpss[u].begin(), akpss[u].end());
vector<int> itrs(N, 0);
using Entry = pair<Int, pair<int, int>>;
priority_queue<Entry, vector<Entry>, greater<Entry>> que;
vector<vector<Int>> dist(K);
vector<vector<int>> vis(N);
for (int k = 0; k < K; ++k) {
dist[k].assign(P[k] + 1, INF);
vis[k].assign(P[k] + 1, 0);
}
for (int k = 0; k < K; ++k) for (int p = 0; p <= P[k]; ++p) if (X[k][p] == 0) {
que.emplace(dist[k][p] = 0, make_pair(k, p));
}
for (; que.size(); ) {
const Int c = que.top().first;
const int k = que.top().second.first;
const int p = que.top().second.second;
que.pop();
if (!vis[k][p]) {
vis[k][p] = 1;
auto visit = [&](int kk, int pp, Int cc) -> void {
if (!vis[kk][pp]) {
if (chmin(dist[kk][pp], cc)) {
que.emplace(cc, make_pair(kk, pp));
}
}
};
if (p > 0) visit(k, p, c + W[k][p - 1]);
if (p < P[k]) visit(k, p + 1, c + W[k][p]);
const int u = X[k][p];
lcts[u].add(Line(B[k], c));
for (int &i = itrs[u]; i < (int)akpss[u].size(); ++i) {
const int kk = akpss[u][i].second.first;
const int pp = akpss[u][i].second.second;
if (!vis[kk][pp]) {
visit(kk, pp, lcts[u](A[kk]));
break;
}
}
}
}
vector<Int> ans(N, INF);
for (int k = 0; k < K; ++k) for (int p = 0; p <= P[k]; ++p) chmin(ans[X[k][p]], dist[k][p]);
for (int u = 1; u < N; ++u) {
if (u > 1) printf(" ");
printf("%lld", ans[u]);
}
puts("");
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 3788kb
input:
6 3 1 5 1 5 5 1 3 1 2 2 3 3 3 5 1 2 1 4 3 3 4 5 4 6
output:
2 5 21 14 18
result:
ok 5 number(s): "2 5 21 14 18"
Test #2:
score: 0
Accepted
time: 0ms
memory: 4104kb
input:
6 3 1 5 1 5 5 1 5 1 2 2 100 3 100 6 1 4 5 1 100 2 4 3 100 5 1 4 2 3 1 5
output:
2 31 43 37 136
result:
ok 5 number(s): "2 31 43 37 136"
Test #3:
score: -100
Runtime Error
input:
5 9 278281 70119 511791 834898 25300 63487 609134 236836 394497 835557 287345 579404 879128 636344 306393 569430 152565 47119 2 3 823004250 4 2 1 25427550 3 2 1 15849621 3 2 1 701911826 5 3 5 679672631 3 907176714 2 2 1 817370554 2 2 3 697987914 2 2 4 873900795 2 2 1 814305954 5