답안 #914847

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
914847 2024-01-22T18:20:44 Z sverma22 Toll (BOI17_toll) C++17
0 / 100
34 ms 16724 KB
#include <bits/stdc++.h>
using namespace std; 

#define int int64_t

int n, k; 

struct Info {
    int L_idx, R_idx, M_idx; 
    vector<vector<int> > lef; 
    int lef_st; 
    vector<vector<int> > rig; 
    int rig_st; 
}; 

map<int, Info> info_map; 

vector<vector<pair<int, int> > > adj; 
vector<vector<pair<int, int> > > rev_adj; 

void djikstra_left(int start_node, int st, int en, vector<int>& dist) {
    priority_queue<pair<int, int> > pq; 
    vector<bool> processed(dist.size(), false); 
    assert(0 <= start_node - st < dist.size()); 
    dist[start_node - st] = 0; 
    pq.push({0, start_node}); 

    while(!pq.empty()) {
        int a = pq.top().second; pq.pop(); 
        if(processed[a]) continue; 
        processed[a] = true; 

        for(auto [b, w] : rev_adj[a]) {
            // if(b > a) continue; // avoid exploring too much ya know
            assert(0 <= a - st < dist.size());
            assert(0 <= b - st < dist.size());  
            if(dist[a - st] + w < dist[b - st]) {
                dist[b - st] = dist[a - st] + w; 
                pq.push({-dist[b - st], b}); 
            }
        }
    }
}

void djikstra_right(int start_node, int st, int en, vector<int>& dist) {
     priority_queue<pair<int, int> > pq; 
    vector<bool> processed(dist.size(), false); 
    assert(0 <= start_node - st < dist.size()); 
    dist[start_node - st] = 0; 
    pq.push({0, start_node}); 

    while(!pq.empty()) {
        int a = pq.top().second; pq.pop(); 
        if(processed[a]) continue; 
        processed[a] = true; 

        for(auto [b, w] : adj[a]) {
            // if(b < a) continue; // avoid extra exploration
            assert(0 <= a - st < dist.size());
            assert(0 <= b - st < dist.size()); 
            if(dist[a - st] + w < dist[b - st]) {
                dist[b - st] = dist[a - st] + w; 
                pq.push({-dist[b - st], b}); 
            }
        }
    }
}



void dvc(int l, int r, int lvl) { // may have to add more params later 
    if(l == r) return; 
    int m = (l + r) / 2;  

    // cout << l << ',' << r << '\n';

    info_map[lvl].L_idx = l; 
    info_map[lvl].R_idx = r; 
    info_map[lvl].M_idx = m; 

    vector<vector<int> > &lef = info_map[lvl].lef; 
    lef.resize(k); 

    // need to populate our fuckers and do a graph search 

    // START: l * k -> END: m * k + k - 1 
    int st = l * k; 
    int en = (m + 1) * k - 1;

    info_map[lvl].lef_st = st; 

    // cout << st << "->" << en << '\n';

    int len = en - st + 1; 

    for(int start_node = m * k; start_node < m * k + k; start_node++) {
        // cout << "START NODE: " << start_node << '\n';

        assert(0 <= start_node - m * k < lef.size()); 
        lef[start_node - m * k].resize(len, INT_MAX); 
        djikstra_left(start_node, st, en, lef[start_node - m * k]);
        // for(int node = st; node <= en; node++) {
        //     int dist = lef[start_node - m * k][node - st];
        //     if(dist == INT_MAX) {
        //         cout << -1 << ' ';
        //     } else cout << dist << ' ';
        // }
        // cout << '\n';
    }

    vector<vector<int> > &rig = info_map[lvl].rig; 
    rig.resize(k); 
    st = (m + 1) * k; 
    en = (r + 1) * k - 1;
    len = en - st + 1; 

    info_map[lvl].rig_st = st; 

    // cout << st << "->" << en << '\n';

    for(int start_node = m * k + k; start_node < m * k + 2 * k; start_node++) {

        assert(0 <= start_node - m * k - k < rig.size()); 
        rig[start_node - m * k - k].resize(len, INT_MAX); 
        djikstra_right(start_node, st, en, rig[start_node - m * k - k]); 
        // for(int node = st; node <= en; node++) {
        //     int dist = rig[start_node - m * k - k][node - st];
        //     if(dist == INT_MAX) {
        //         cout << -1 << ' ';
        //     } else cout << dist << ' ';
        // }
        // cout << '\n';
    }

    dvc(l, m, 2 * lvl); 
    dvc(m + 1, r, 2 * lvl + 1); 
}

int query(int a, int b) {

    int ai = a / k, bi = b/ k; 

    int lvl = 1; 
    while(true) {
        int m = info_map[lvl].M_idx; 
        if(ai <= m && m < bi) {
            
            int best = INT_MAX; 

            for(int i = m * k; i < m * k + k; i++) {
                int lef_cheese = info_map[lvl].lef[i - m * k][a - info_map[lvl].lef_st];
                if(lef_cheese == INT_MAX) continue; 
                for(auto [j, w] : adj[i]) {
                    int rig_cheese = info_map[lvl].rig[j - m * k - k][b - info_map[lvl].rig_st]; 
                    if(rig_cheese == INT_MAX) continue; 
                    best = min(best, lef_cheese + w + rig_cheese); 
                }
            }

            if(best == INT_MAX) best = -1; 
            return best; 
        } else if(ai > m) { // go to right side 
            lvl = 2 * lvl + 1; 
        } else { // go to left side 
            lvl = 2 * lvl; 
        }
    }

    return -1; 
}


void solve() {
    int m, o; 
    cin >> k >> n >> m >> o; 

    adj.resize(n + 1); 
    rev_adj.resize(n + 1); 

    for(int i = 0; i < m; i++) {
        int a, b, t; cin >> a >> b >> t; 
        adj[a].push_back({b, t}); 
        rev_adj[b].push_back({a, t}); 
    }

    // run the divide and conquer 
    dvc(0, n / k, 1); 

    for(int i = 0; i < o; i++) { // process queries 
        int a, b; cin >> a >> b; 
        cout << query(a, b) << '\n';
    }

}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    // #ifndef ONLINE_JUDGE
    // freopen("file.txt", "r", stdin);
    // #endif
    int t = 1; // cin >> t; 
    while(t--) {
        solve(); 
    }
}

Compilation message

In file included from /usr/include/c++/10/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:33,
                 from toll.cpp:1:
toll.cpp: In function 'void djikstra_left(int64_t, int64_t, int64_t, std::vector<long int>&)':
toll.cpp:24:14: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
   24 |     assert(0 <= start_node - st < dist.size());
      |            ~~^~~~~~~~~~~~~~~~~~
toll.cpp:35:22: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
   35 |             assert(0 <= a - st < dist.size());
      |                    ~~^~~~~~~~~
toll.cpp:36:22: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
   36 |             assert(0 <= b - st < dist.size());
      |                    ~~^~~~~~~~~
toll.cpp: In function 'void djikstra_right(int64_t, int64_t, int64_t, std::vector<long int>&)':
toll.cpp:48:14: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
   48 |     assert(0 <= start_node - st < dist.size());
      |            ~~^~~~~~~~~~~~~~~~~~
toll.cpp:59:22: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
   59 |             assert(0 <= a - st < dist.size());
      |                    ~~^~~~~~~~~
toll.cpp:60:22: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
   60 |             assert(0 <= b - st < dist.size());
      |                    ~~^~~~~~~~~
toll.cpp: In function 'void dvc(int64_t, int64_t, int64_t)':
toll.cpp:99:18: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
   99 |         assert(0 <= start_node - m * k < lef.size());
      |                ~~^~~~~~~~~~~~~~~~~~~~~
toll.cpp:123:18: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
  123 |         assert(0 <= start_node - m * k - k < rig.size());
      |                ~~^~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Runtime error 19 ms 11608 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 34 ms 16724 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 600 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 600 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 19 ms 11608 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -