#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define pb push_back
#define pp pop_back
#define pf push_front
#define pt pop_front
#define fi first
#define se second
#define lb lower_bound
#define ub upper_bound
#define pll pair<ll,ll>
#define pii pair<int,int>
#define vl vector<ll>
#define endl "\n"
#define fr(i,a,b) for(ll i=a; i<=b; i++)
#define fre(i,a,b) for(ll i=a; i>=b; i--)
#define kpnyh ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const ll INF = (ll)4e18;
ll te,n,m,k,q;
vector<vector<vector<ll>>> st, mtx; // segtree & base matrices
vector<vector<ll>> make_inf_mat(){
return vector<vector<ll>>( (size_t)k, vector<ll>((size_t)k, INF) );
}
vector<vector<ll>> multiply_mat(const vector<vector<ll>> &A, const vector<vector<ll>> &B){
vector<vector<ll>> C = make_inf_mat();
for (ll i=0;i<k;i++){
for (ll p=0;p<k;p++){
ll aip = A[i][p];
if (aip == INF) continue;
for (ll j=0;j<k;j++){
ll bpj = B[p][j];
if (bpj == INF) continue;
ll cand = aip + bpj;
if (cand < C[i][j]) C[i][j] = cand;
}
}
}
return C;
}
// build segtree on [l..r] of base (base size = leafCount)
void build(ll l, ll r, ll idx){
if (l == r){
st[idx] = mtx[l];
return;
}
ll mid = (l + r) >> 1;
build(l, mid, idx<<1);
build(mid+1, r, idx<<1|1);
st[idx] = multiply_mat(st[idx<<1], st[idx<<1|1]); // left ⊗ right
}
vector<vector<ll>> ans; // accumulated product during query
// ans = ans ⊗ M (in-place)
void ans_mul_with(const vector<vector<ll>> &M){
vector<vector<ll>> res = make_inf_mat();
for (ll i=0;i<k;i++){
for (ll p=0;p<k;p++){
ll aip = ans[i][p];
if (aip == INF) continue;
for (ll j=0;j<k;j++){
ll b = M[p][j];
if (b == INF) continue;
ll cand = aip + b;
if (cand < res[i][j]) res[i][j] = cand;
}
}
}
ans.swap(res);
}
// query segtree accumulate into ans; segtree covers [l,r]; query range [x,y]
void qry(ll l, ll r, ll x, ll y, ll idx){
if (l > y || r < x) return;
if (l >= x && r <= y){
ans_mul_with(st[idx]);
return;
}
ll mid = (l + r) >> 1;
qry(l, mid, x, y, idx<<1);
qry(mid+1, r, x, y, idx<<1|1);
}
void solve(){
cin >> k >> n >> m >> q;
// compute number of layers L and number of transitions (base matrices) leafCount
ll L = (n + k - 1) / k;
ll leafCount = max(0LL, L - 1);
// allocate base matrices for transitions only
if (leafCount > 0) mtx.assign((size_t)leafCount, make_inf_mat());
else mtx.clear();
// read edges: keep only edges from layer u to layer u+1 and within range
for (ll i=0;i<m;i++){
ll u,v,w; cin >> u >> v >> w;
if (u < 0 || v < 0 || u >= n || v >= n) continue;
ll lu = u / k;
ll lv = v / k;
if (lv != lu + 1) continue; // only adjacent-layer edges
if (lu < 0 || lu >= leafCount) continue;
int pu = (int)(u % k);
int pv = (int)(v % k);
mtx[(size_t)lu][pu][pv] = min(mtx[(size_t)lu][pu][pv], w);
}
int segN = max(1LL, leafCount);
st.assign(4 * segN, make_inf_mat());
if (leafCount > 0) build(0, leafCount-1, 1);
// identity matrix
vector<vector<ll>> I = make_inf_mat();
for (int i=0;i<k;i++) I[i][i] = 0;
while (q--){
ll a,b; cin >> a >> b;
if (a < 0 || b < 0 || a >= n || b >= n){
cout << -1 << endl; continue;
}
ll sa = a / k, sb = b / k;
int pa = (int)(a % k), pb = (int)(b % k);
if (sa == sb){
cout << (a==b ? 0 : -1) << endl; continue;
}
if (sa > sb){ cout << -1 << endl; continue; }
if (leafCount == 0){ cout << -1 << endl; continue; }
ll L_from = sa;
ll L_to = sb - 1; // product A_{sa} .. A_{sb-1}
if (L_from < 0) L_from = 0;
if (L_to < L_from || L_to >= leafCount){ cout << -1 << endl; continue; }
// init ans = identity
ans = I;
qry(0, leafCount-1, L_from, L_to, 1);
ll res = ans[pa][pb];
if (res >= INF/2) cout << -1 << endl;
else cout << res << endl;
}
}
int main(){
kpnyh
te = 1;
while (te--) solve();
return 0;
}
| # | 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... |