This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |