1
+ /* *
2
+ * @file 3356.cpp
3
+ * @author Macesuted ([email protected] )
4
+ * @date 2024-07-10
5
+ *
6
+ * @copyright Copyright (c) 2024
7
+ * @brief
8
+ * O(n^(2/3) * q^(2/3) * k^(5/3))
9
+ *
10
+ */
11
+
12
+ #include < bits/stdc++.h>
13
+ using namespace std ;
14
+
15
+ #ifndef LOCAL
16
+ #define endl ' \n '
17
+ #endif
18
+
19
+ bool mem1;
20
+
21
+ #define maxn 50005
22
+ #define maxB 1005
23
+ #define maxk 5
24
+
25
+ typedef pair<int , int > pii;
26
+
27
+ vector<pii> graph[maxn], rgraph[maxn];
28
+ int bl[maxB], bel[maxn];
29
+ int64_t distL[maxk][maxn], distR[maxk][maxn], dist[maxB][maxB][maxk][maxk], distc[maxn];
30
+ queue<int > que;
31
+
32
+ void solve (void ) {
33
+ int K, n, m, q;
34
+ cin >> K >> n >> m >> q;
35
+ n = n / K + (n % K != 0 ) - 1 ;
36
+ 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);
37
+
38
+ auto _ = [&](int x, int y) { return x * K + y; };
39
+
40
+ int B = min (n, (int )max ({1 ., n / 1000 ., pow ((double )n * n * K / q, 1 . / 3 )})), bcnt = 0 ;
41
+ bl[0 ] = 0 ;
42
+ while (bl[bcnt] < n) bl[bcnt + 1 ] = bl[bcnt] + B, bcnt++;
43
+ if (bl[bcnt] > n) bl[bcnt] = n;
44
+ for (int i = 0 ; i < bcnt; i++)
45
+ for (int j = bl[i]; j < bl[i + 1 ]; j++) bel[j] = i;
46
+ bel[n] = bcnt;
47
+
48
+ memset (distL, 0x3f , sizeof (distL)), memset (distR, 0x3f , sizeof (distR)), memset (dist, 0x3f , sizeof (dist));
49
+ for (int i = 0 ; i < bcnt; i++) {
50
+ for (int o = 0 ; o < K; o++) {
51
+ distL[o][_ (bl[i], o)] = 0 , que.push (_ (bl[i], o));
52
+ while (!que.empty ()) {
53
+ int p = que.front ();
54
+ que.pop ();
55
+ for (auto [t, v] : graph[p])
56
+ if (t < _ (bl[i + 1 ], 0 )) {
57
+ if (distL[o][t] == 0x3f3f3f3f3f3f3f3f ) que.push (t);
58
+ distL[o][t] = min (distL[o][t], distL[o][p] + v);
59
+ }
60
+ }
61
+ }
62
+ for (int o = 0 ; o < K; o++) {
63
+ for (auto [t, v] : rgraph[_ (bl[i + 1 ], o)]) distR[o][t] = v, que.push (t);
64
+ while (!que.empty ()) {
65
+ int p = que.front ();
66
+ que.pop ();
67
+ for (auto [t, v] : rgraph[p])
68
+ if (t >= _ (bl[i], 0 )) {
69
+ if (distR[o][t] == 0x3f3f3f3f3f3f3f3f ) que.push (t);
70
+ distR[o][t] = min (distR[o][t], distR[o][p] + v);
71
+ }
72
+ }
73
+ }
74
+ for (int x = 0 ; x < K; x++)
75
+ for (int y = 0 ; y < K; y++) dist[i][i + 1 ][x][y] = distR[y][_ (bl[i], x)];
76
+ }
77
+ for (int i = 0 ; i < bcnt; i++)
78
+ for (int j = i + 2 ; j <= bcnt; j++)
79
+ for (int x = 0 ; x < K; x++)
80
+ for (int y = 0 ; y < K; y++)
81
+ for (int z = 0 ; z < K; z++)
82
+ if (dist[i][j - 1 ][x][z] != 0x3f3f3f3f3f3f3f3f && dist[j - 1 ][j][z][y] != 0x3f3f3f3f3f3f3f3f )
83
+ dist[i][j][x][y] = min (dist[i][j][x][y], dist[i][j - 1 ][x][z] + dist[j - 1 ][j][z][y]);
84
+ for (int i = 0 ; i <= bcnt; i++)
85
+ for (int x = 0 ; x < K; x++) dist[i][i][x][x] = 0 ;
86
+ for (int i = 0 ; i < K; i++) distL[i][_ (n, i)] = 0 ;
87
+
88
+ while (q--) {
89
+ int a, b;
90
+ cin >> a >> b;
91
+ int na = a / K, nb = b / K, bela = bel[na], belb = bel[nb];
92
+ if (bela == belb) {
93
+ for (int i = a; i <= b; i++) distc[i] = INT64_MAX;
94
+ distc[a] = 0 ;
95
+ for (int i = a; i <= b; i++)
96
+ if (distc[i] != INT64_MAX)
97
+ for (auto [t, v] : graph[i]) distc[t] = min (distc[t], distc[i] + v);
98
+ cout << (distc[b] == INT64_MAX ? -1 : distc[b]) << endl;
99
+ continue ;
100
+ }
101
+
102
+ int64_t ans = INT64_MAX;
103
+ for (int x = 0 ; x < K; x++)
104
+ if (distR[x][a] != 0x3f3f3f3f3f3f3f3f )
105
+ for (int y = 0 ; y < K; y++)
106
+ if (distL[y][b] != 0x3f3f3f3f3f3f3f3f && dist[bela + 1 ][belb][x][y] != 0x3f3f3f3f3f3f3f3f )
107
+ ans = min (ans, distR[x][a] + dist[bela + 1 ][belb][x][y] + distL[y][b]);
108
+
109
+ cout << (ans == INT64_MAX ? -1 : ans) << endl;
110
+ }
111
+ return ;
112
+ }
113
+
114
+ bool mem2;
115
+
116
+ int main () {
117
+ ios::sync_with_stdio (false ), cin.tie (nullptr );
118
+ #ifdef LOCAL
119
+ cerr << " Memory Cost: " << abs (&mem1 - &mem2) / 1024 . / 1024 . << " MB" << endl;
120
+ #endif
121
+
122
+ int _ = 1 ;
123
+ while (_--) solve ();
124
+
125
+ #ifdef LOCAL
126
+ cerr << " Time Cost: " << clock () * 1000 . / CLOCKS_PER_SEC << " MS" << endl;
127
+ #endif
128
+ return 0 ;
129
+ }
0 commit comments