From 931e4da4293ddfdbb8235a8bcb42f71235b224c1 Mon Sep 17 00:00:00 2001 From: Macesuted Date: Thu, 11 Jul 2024 10:51:31 +0800 Subject: [PATCH] =?UTF-8?q?LibreOJ:=203356=20=E3=80=8CBalticOI=202017=20Da?= =?UTF-8?q?y1=E3=80=8DToll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 2 +- LibreOJ/{3356.cpp => 3356-1.cpp} | 0 LibreOJ/3356-2.cpp | 129 +++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) rename LibreOJ/{3356.cpp => 3356-1.cpp} (100%) create mode 100644 LibreOJ/3356-2.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json index a97349c..09c6e28 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -40,7 +40,7 @@ "resmon.updatefrequencyms": 500, "task.quickOpen.skip": false, "terminal.integrated.defaultProfile.windows": "PowerShell", - "workbench.colorTheme": "Material Theme Lighter High Contrast", + "workbench.colorTheme": "Material Theme Darker High Contrast", "workbench.iconTheme": "material-icon-theme", "workbench.list.smoothScrolling": true, "workbench.settings.openDefaultKeybindings": false, diff --git a/LibreOJ/3356.cpp b/LibreOJ/3356-1.cpp similarity index 100% rename from LibreOJ/3356.cpp rename to LibreOJ/3356-1.cpp diff --git a/LibreOJ/3356-2.cpp b/LibreOJ/3356-2.cpp new file mode 100644 index 0000000..621d337 --- /dev/null +++ b/LibreOJ/3356-2.cpp @@ -0,0 +1,129 @@ +/** + * @file 3356.cpp + * @author Macesuted (i@macesuted.moe) + * @date 2024-07-10 + * + * @copyright Copyright (c) 2024 + * @brief + * O(n^(2/3) * q^(2/3) * k^(5/3)) + * + */ + +#include +using namespace std; + +#ifndef LOCAL +#define endl '\n' +#endif + +bool mem1; + +#define maxn 50005 +#define maxB 1005 +#define maxk 5 + +typedef pair pii; + +vector graph[maxn], rgraph[maxn]; +int bl[maxB], bel[maxn]; +int64_t distL[maxk][maxn], distR[maxk][maxn], dist[maxB][maxB][maxk][maxk], distc[maxn]; +queue que; + +void solve(void) { + int K, n, m, q; + cin >> K >> n >> m >> q; + n = n / K + (n % K != 0) - 1; + for (int i = 1, x, y, t; i <= m; i++) cin >> x >> y >> t, graph[x].emplace_back(y, t), rgraph[y].emplace_back(x, t); + + auto _ = [&](int x, int y) { return x * K + y; }; + + int B = min(n, (int)max({1., n / 1000., pow((double)n * n * K / q, 1. / 3)})), bcnt = 0; + bl[0] = 0; + while (bl[bcnt] < n) bl[bcnt + 1] = bl[bcnt] + B, bcnt++; + if (bl[bcnt] > n) bl[bcnt] = n; + for (int i = 0; i < bcnt; i++) + for (int j = bl[i]; j < bl[i + 1]; j++) bel[j] = i; + bel[n] = bcnt; + + memset(distL, 0x3f, sizeof(distL)), memset(distR, 0x3f, sizeof(distR)), memset(dist, 0x3f, sizeof(dist)); + for (int i = 0; i < bcnt; i++) { + for (int o = 0; o < K; o++) { + distL[o][_(bl[i], o)] = 0, que.push(_(bl[i], o)); + while (!que.empty()) { + int p = que.front(); + que.pop(); + for (auto [t, v] : graph[p]) + if (t < _(bl[i + 1], 0)) { + if (distL[o][t] == 0x3f3f3f3f3f3f3f3f) que.push(t); + distL[o][t] = min(distL[o][t], distL[o][p] + v); + } + } + } + for (int o = 0; o < K; o++) { + for (auto [t, v] : rgraph[_(bl[i + 1], o)]) distR[o][t] = v, que.push(t); + while (!que.empty()) { + int p = que.front(); + que.pop(); + for (auto [t, v] : rgraph[p]) + if (t >= _(bl[i], 0)) { + if (distR[o][t] == 0x3f3f3f3f3f3f3f3f) que.push(t); + distR[o][t] = min(distR[o][t], distR[o][p] + v); + } + } + } + for (int x = 0; x < K; x++) + for (int y = 0; y < K; y++) dist[i][i + 1][x][y] = distR[y][_(bl[i], x)]; + } + for (int i = 0; i < bcnt; i++) + for (int j = i + 2; j <= bcnt; j++) + for (int x = 0; x < K; x++) + for (int y = 0; y < K; y++) + for (int z = 0; z < K; z++) + if (dist[i][j - 1][x][z] != 0x3f3f3f3f3f3f3f3f && dist[j - 1][j][z][y] != 0x3f3f3f3f3f3f3f3f) + dist[i][j][x][y] = min(dist[i][j][x][y], dist[i][j - 1][x][z] + dist[j - 1][j][z][y]); + for (int i = 0; i <= bcnt; i++) + for (int x = 0; x < K; x++) dist[i][i][x][x] = 0; + for (int i = 0; i < K; i++) distL[i][_(n, i)] = 0; + + while (q--) { + int a, b; + cin >> a >> b; + int na = a / K, nb = b / K, bela = bel[na], belb = bel[nb]; + if (bela == belb) { + for (int i = a; i <= b; i++) distc[i] = INT64_MAX; + distc[a] = 0; + for (int i = a; i <= b; i++) + if (distc[i] != INT64_MAX) + for (auto [t, v] : graph[i]) distc[t] = min(distc[t], distc[i] + v); + cout << (distc[b] == INT64_MAX ? -1 : distc[b]) << endl; + continue; + } + + int64_t ans = INT64_MAX; + for (int x = 0; x < K; x++) + if (distR[x][a] != 0x3f3f3f3f3f3f3f3f) + for (int y = 0; y < K; y++) + if (distL[y][b] != 0x3f3f3f3f3f3f3f3f && dist[bela + 1][belb][x][y] != 0x3f3f3f3f3f3f3f3f) + ans = min(ans, distR[x][a] + dist[bela + 1][belb][x][y] + distL[y][b]); + + cout << (ans == INT64_MAX ? -1 : ans) << endl; + } + return; +} + +bool mem2; + +int main() { + ios::sync_with_stdio(false), cin.tie(nullptr); +#ifdef LOCAL + cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl; +#endif + + int _ = 1; + while (_--) solve(); + +#ifdef LOCAL + cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl; +#endif + return 0; +} \ No newline at end of file