Submission #762845

#TimeUsernameProblemLanguageResultExecution timeMemory
762845ThegeekKnight16Toll (BOI17_toll)C++17
100 / 100
257 ms28716 KiB
#include <bits/stdc++.h> using namespace std; const int MAXN = 5e4 + 10; const int INF = 0x3f3f3f3f; array<vector<pair<int, int> >, MAXN> grafo; int K, N, M, O; struct node { //Niveis do comeco e do fim, respectivamente int X, Y; array<array<int, 5>, 5> dist; node(int x = 0, int y = 0) : X(x), Y(y) { dist[0] = {0, INF, INF, INF, INF}; dist[1] = {INF, 0, INF, INF, INF}; dist[2] = {INF, INF, 0, INF, INF}; dist[3] = {INF, INF, INF, 0, INF}; dist[4] = {INF, INF, INF, INF, 0}; } //O(K⁴) ≃ 625 node operator+(node outro) const { if (X == -1) return outro; if (outro.X == -1) return *this; node resp; // cerr << X << " " << Y << " " << outro.X << " " << outro.Y << '\n'; //Novo X for (int k = 0; k < K; k++) { //Novo Y for (int k2 = 0; k2 < K; k2++) { resp.dist[k][k2] = INF; //Intermediario da esquerda (final) for (int i = 0, v = Y*K; i < K; i++, v++) { //Intermediario da direira (comeco) for (auto [viz, p] : grafo[v]) { // cerr << k << " " << i << " " << viz << " " << k2 << '\n'; // k -> k2 = k -> v ---------> viz -> k2 resp.dist[k][k2] = min(resp.dist[k][k2], dist[k][i] + p + outro.dist[viz%K][k2]); } } } } resp.X = X; resp.Y = outro.Y; /*for (int i = 0; i < K; i++) { for (int j = 0; j < K; j++) { cerr << (resp.dist[i][j] == INF ? -1 : resp.dist[i][j]) << " "; } cerr << '\n'; }*/ // cerr << '\n'; return resp; } } seg[4*MAXN]; node nulo(-1, -1); //O(4*N*K⁴) ≃ 1.25e8 void build(int pos, int ini, int fim) { if (ini == fim) { seg[pos] = node(ini, ini); return; } int m = (ini + fim) >> 1; int e = 2*pos; int d = 2*pos + 1; build(e, ini, m ); build(d, m+1, fim); seg[pos] = seg[e] + seg[d]; // cerr << "Soma funciona!" << '\n'; } //O(logN*K⁴) ≃ 1e4 p/ query node query(int pos, int ini, int fim, int p, int q) { if (q < ini || p > fim) return nulo; if (p <= ini && fim <= q) return seg[pos]; int m = (ini + fim) >> 1; int e = 2*pos; int d = 2*pos + 1; return query(e, ini, m, p, q) + query(d, m+1, fim, p, q); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> K >> N >> M >> O; // cerr << "PENIS" << '\n'; for (int i = 0; i < M; i++) { int X, Y, P; cin >> X >> Y >> P; grafo[X].emplace_back(Y, P); } // cerr << "PENIS" << '\n'; build(1, 0, N/K); // cerr << "PENIS" << '\n'; for (int i = 0; i < O; i++) { int X, Y; cin >> X >> Y; if (X/K >= Y/K) {cout << "-1" << '\n'; continue;} // cerr << "||" << X << " " << X/K << " " << Y << " " << Y/K << '\n'; node resp = query(1, 0, N/K, X/K, Y/K); /*for (int i = 0; i < K; i++) { for (int j = 0; j < K; j++) { cerr << (resp.dist[i][j] == INF ? -1 : resp.dist[i][j]) << " "; } cerr << '\n'; }*/ cout << (resp.dist[X%K][Y%K] == INF ? -1 : resp.dist[X%K][Y%K]) << '\n'; } // cerr << "PENIS" << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...