제출 #1333511

#제출 시각아이디문제언어결과실행 시간메모리
1333511nguyenkhangninh99Event Hopping 2 (JOI21_event2)C++20
100 / 100
187 ms43648 KiB
#include<bits/stdc++.h>
using namespace std;

#define int long long
const int maxn = 4e5 + 5; 
int jump[20][maxn];

int calc(int l, int r){
    int cur = l, cnt = 0;
    for(int i = 19; i >= 0; i--){
        if(jump[i][cur] <= r){
            cur = jump[i][cur];
            cnt += (1 << i);
        }
    }
    return cnt;
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, k; cin >> n >> k;

    vector<int> l(n + 1), r(n + 1), compress;
    for(int i = 1; i <= n; i++){
        cin >> l[i] >> r[i];
        compress.push_back(l[i]);
        compress.push_back(r[i]);
    }

    sort(compress.begin(), compress.end());
    compress.erase(unique(compress.begin(), compress.end()), compress.end());
    
    auto get = [&](int v) -> int {
        return lower_bound(compress.begin(), compress.end(), v) - compress.begin();
    };

    int m = compress.size() - 1;
    vector<int> mnr(m + 1, m + 1);
    for(int i = 1; i <= n; i++) mnr[get(l[i])] = min(mnr[get(l[i])], get(r[i]));
    for(int i = m - 1; i >= 0; i--) mnr[i] = min(mnr[i], mnr[i + 1]);

    for(int i = 0; i <= m; i++) jump[0][i] = mnr[i];
    for(int i = 0; i <= 19; i++) jump[i][m + 1] = m + 1;
    for(int j = 1; j <= 19; j++){
        for(int i = 0; i <= m; i++) jump[j][i] = jump[j - 1][jump[j - 1][i]];
    }

    set<pair<int, int>> s;
    s.insert({0, m});
    
    int cur = calc(0, m);
    vector<int> res;

    for(int i = 1; i <= n; i++){
        int ll = get(l[i]), rr = get(r[i]);
        auto it = s.upper_bound({ll, 1e18});
        
        if(it != s.begin()){
            auto [lbound, rbound] = *prev(it);
            if(rr <= rbound){
                int avail = cur - calc(lbound, rbound) + calc(lbound, ll) + calc(rr, rbound) + 1;
                if(avail >= k){
                    res.push_back(i);
                    cur = avail;
                    
                    s.erase(prev(it));
                    if(lbound < ll) s.insert({lbound, ll});
                    if(rr < rbound) s.insert({rr, rbound});
                    
                }
            }
            if(res.size() == k) break;
        }
    }

    if(res.size() < k) res = {-1};
    for(int x: res) cout << x << "\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...