제출 #1333431

#제출 시각아이디문제언어결과실행 시간메모리
1333431SzymonKrzywda치료 계획 (JOI20_treatment)C++20
4 / 100
463 ms83992 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>

#define int ll

using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define ff first
#define ss second

const int MAXM = 1e5 + 7;
ll dp[MAXM];

int n;
bool inter(int b, int a2, int d, int d2) {
    int r = abs(d - d2);
    return (b + 1) - r >= a2;
}

const int base = 1 << 18;
vector<pair<int, int>> tree[2 * base]; //{y, nr}

void add(int x, int y, int nr) {
    x += base;
    tree[x].push_back({y, nr});
}

void build(int v) {
    if (v >= base) {
        sort(tree[v].begin(), tree[v].end(), [&](pii a, pii b){return a.ff > b.ff;});
        return;
    }
    build(v * 2);
    build(v * 2 + 1);
    vector<pii> tab1 = tree[v * 2];
    vector<pii> tab2 = tree[v * 2 + 1];
    while (tab1.size() && tab2.size()) {
        if (tab1.back().ff > tab2.back().ff) {
            tree[v].push_back(tab1.back());
            tab1.pop_back();
        }
        else {
            tree[v].push_back(tab2.back());
            tab2.pop_back();
        }
    }
    if (tab1.size()) for (auto & val : tab1) tree[v].push_back(val);
    if (tab2.size()) for (auto & val : tab2) tree[v].push_back(val);
}

vector<int> query(int x, int y) {
    vector<int> punkty;
    int l = 1 + base - 1;
    int r = x + base + 1;
    while (l / 2 != r / 2) {
        if (l % 2 == 0) {
            while (tree[l + 1].size()) {
                if (dp[tree[l + 1].back().ss] != 1e18) tree[l + 1].pop_back();
                else if (tree[l + 1].back().ff <= y) {
                    punkty.push_back(tree[l + 1].back().ss);
                    tree[l + 1].pop_back();
                }
                else break;
            }
        }
        if (r % 2 == 1) {
            while (tree[r - 1].size()) {
                if (dp[tree[r - 1].back().ss] != 1e18) tree[r - 1].pop_back();
                else if (tree[r - 1].back().ff <= y) {
                    punkty.push_back(tree[r - 1].back().ss);
                    tree[r - 1].pop_back();
                }
                else break;
            }
        }
        l /= 2;
        r /= 2;
    }
    return punkty;
}


int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int m, a, b, c, d;
    cin >> n >> m;


    map<int, int> skalax;
    map<int, int> skalay;
    vector<pair<pii, pii>> tab;
    for (int i = 0; i < m; i++) {
        cin >> a >> b >> c >> d;
        tab.push_back({{b, c}, {a, d}});
        skalax[c + a + 1] = 0;
        skalax[b + a] = 0;
        skalay[b - a] = 0;
        skalay[c + 1 - a] = 0;
        //cout << c + a + 1 << ' ' << c + 1 - a  << ' ' << b + a  << ' ' << b - a << '\n';
    }

    int wsk = 1;
    for (auto & [k, v] : skalax) {
        v = wsk++;
    }
    wsk = 1;
    for (auto & [k, v] : skalay) {
        v = wsk++;
    }

    priority_queue<pii, vector<pii>, greater<pii>> kolejka;
    for (int i = 0; i < m; i++) {
        dp[i] = 1e18; 
        if (tab[i].ff.ff == 1) {
            dp[i] = tab[i].ss.ss;
            kolejka.push({tab[i].ss.ss, i});
        }
        else {
            add(skalax[tab[i].ff.ff + tab[i].ss.ff], skalay[tab[i].ff.ff - tab[i].ss.ff], i);
        }
    }
    ll ans = 1e18;  
    build(1);

    while (!kolejka.empty()) {
        int v = kolejka.top().ss;
        int c = kolejka.top().ff;
       // cout << v << ' ' << c << '\n';
        if (tab[v].ff.ss == n) ans = min(ans, dp[v]);
        kolejka.pop();
        vector<int> t = query(skalax[tab[v].ff.ss + tab[v].ss.ff + 1], skalay[tab[v].ff.ss + 1 - tab[v].ss.ff]);
        for (int j : t){
            if (dp[j] != 1e18) continue;
            dp[j] = dp[v] + tab[j].ss.ss;
            kolejka.push({dp[j], j});
        }

    }



   
    if (ans == 1e18) ans = -1;
    cout << ans << '\n';





    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...