제출 #1333361

#제출 시각아이디문제언어결과실행 시간메모리
1333361rainmarEvent Hopping (BOI22_events)C++20
25 / 100
324 ms51296 KiB
#include<bits/stdc++.h>
using namespace std;

#define sg pair<int,int>
#define f first
#define s second

#define N 131072*2
#define INF 2e9
pair<int,int> numb[N * 2] = {};
multiset<pair<int,int>> hv[N];

void remove(int pos, pair<int,int> val) {
    auto it = hv[pos].find(val);
    if(it != hv[pos].end()) hv[pos].erase(it);

    int start = pos + N;
    numb[start] = (*(hv[pos].begin()));

    start = start/2;

    while(start>0) {
        //cout << "wow " << numb[start].first << " " << numb[start].second << endl;
        if(numb[start*2].f < numb[start*2+1].f) {
            numb[start] = numb[start*2];
        } else {
            numb[start] = numb[start*2+1];
        }

        start = start/2;
    }
}

void sett(int pos, int val, int i) {
    hv[pos].insert({val,i});
    int start = pos + N;
    numb[start] = (*(hv[pos].begin()));

    start = start/2;

    while(start>0) {
        //cout << "wow " << numb[start].first << " " << numb[start].second << endl;
        if(numb[start*2].f < numb[start*2+1].f) {
            numb[start] = numb[start*2];
        } else {
            numb[start] = numb[start*2+1];
        }

        start = start/2;
    }
}



pair<int,int> query(int l, int r) {
    pair<int,int> ans = {INF,-1};
    for(l += N, r += N; l<r; l=l/2,r=r/2) {
        if(l%2) {
            if(numb[l].first < ans.first) {
                ans = numb[l];
            } else {

            }
            l++;
        }
        if(r%2) {
            r++;
            if(numb[r].first < ans.first) {
                ans = numb[r];
            } else {

            }
        }
    }
    return ans;
}


int jmp[100001][18] = {};


int main() {

    for(int i = 0; i < N * 2; i++) {
        numb[i] = {2e9,-1};
    }
    for(int i = 0; i < N; i++) {
        hv[i].insert({INF,-1});
    }

    //freopen("e.txt", "r", stdin);

    vector<sg> seg;

    int n,q; cin >> n >> q;

    vector<int> vals;

    for(int i = 0; i < n; i++) {
        int a,b; cin >> a >> b;
        seg.push_back({a,b});
        vals.push_back(a);
        vals.push_back(b);
    }
    vals.push_back(0);

    sort(vals.begin(),vals.end());
    vals.erase(unique(vals.begin(),vals.end()),vals.end());

    for(int i = 0; i < n; i++) {
        sg t = seg[i];
        t.f = lower_bound(vals.begin(),vals.end(), t.f) - vals.begin();
        t.s = lower_bound(vals.begin(),vals.end(), t.s) - vals.begin();
        seg[i] = t;
    }

    vector<vector<pair<sg,int>>> ev(vals.size());

    for(int i = 0; i < n; i++) {
        sg t = seg[i];
        //ev[t.f].push_back({{t.f, t.s}, i});
        ev[t.s].push_back({{t.f, t.s}, i}); 
    }


    //init to 0, so no worry
    jmp[0][0] = 0;
    for(int i = 0; i < n; i++){ 
        for(int j = 0; j < 18; j++) jmp[i][j] = i;
    }

    for(int i = 1; i < ev.size(); i++) {
        
        for(auto e : ev[i]) {
            if(e.f.f > 0) {
                sett(e.f.s, e.f.f, e.s);
            }
        }
        for(auto e : ev[i]) {
            if(e.f.f > 0) {

                pair<int,int> res = query(e.f.f, e.f.s+1);
                if(res.second == -1) continue;

                int ch = res.second;
                
                //if(seg[ch].second > seg[e.second].second) continue;

                jmp[e.second][0] = ch;
                
            }
        }
    }

    for(int j = 1; j < 18; j++) {
        for(int i = 0; i < n; i++) {
            jmp[i][j] = jmp[jmp[i][j-1]][j-1];
        }
    }


    for(int k = 0; k < q; k++) {
        int a,b; cin >> a >> b;

        a--; b--;

        int x1,x2;
        x1 = seg[a].f;
        x2 = seg[a].s;

        int ans = 0;

        if(a == b) {
            cout << 0 << endl;
            continue;
        }

        if(seg[a].second > seg[b].second) {
            cout << "impossible" << endl;
            continue;
        }

        if(seg[b].first <= seg[a].second) {
            cout << "1" << endl;
            continue;
        }

        for(int i = 17; i >= 0; i--) {
            //if 2 pow i back is still before it
            int y = jmp[b][i];
            sg t = seg[y];

            if(b==y) continue;

            if(x2 < t.first) {
                ans += (1 << i);
                b = y;
            }
        }
        //361 362
        //896 897

        ans++;
        b = jmp[b][0];

        if((seg[b].first <= x2 and seg[b].second >= x2) or a==b) {
            cout << ans + 1 << endl;
            continue;
        } else {
            cout << "impossible" << endl;
            continue;
        }

    }

}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...