제출 #597342

#제출 시각아이디문제언어결과실행 시간메모리
597342yanndevEvent Hopping (BOI22_events)C++17
20 / 100
430 ms30348 KiB
#include <bits/stdc++.h> #define int long long #define fi first #define se second using namespace std; struct Inter { int rl; int rr; int id; bool operator<(const Inter& other) const { if (rr != other.rr) return rr < other.rr; if (rl != other.rl) return rl < other.rl; return id < other.id; } }; const int MX_N = 1e5 + 42; const int TREE_SIZE = (int)1 << 19; int rl[MX_N]; int rr[MX_N]; int jump[20][MX_N]; int tree[2 * TREE_SIZE + 42]; void insert(int idx, int val, bool force = false) { idx += TREE_SIZE; if (force || rl[val] < rl[tree[idx]]) tree[idx] = val; for (int i = idx / 2; i > 0; i /= 2) { if (rl[tree[2 * i]] < rl[tree[2 * i + 1]]) tree[i] = tree[2 * i]; else tree[i] = tree[2 * i + 1]; } } int query(int left, int right) { left += TREE_SIZE; right += TREE_SIZE; int mnVal = 1e9; int id = -1; while (left <= right) { if (left % 2 == 1) { int newId = tree[left]; if (rl[newId] < mnVal) { mnVal = rl[newId]; id = newId; } left++; } if (right % 2 == 0) { int newId = tree[right]; if (rl[newId] < mnVal) { mnVal = rl[newId]; id = newId; } right--; } left /= 2; right /= 2; } return id; } signed main() { int n, q; cin >> n >> q; vector<Inter> ranges {}; vector<int> vals {}; for (int i = 0; i < n; i++) { cin >> rl[i] >> rr[i]; vals.push_back(rl[i]); vals.push_back(rr[i]); } sort(vals.begin(), vals.end()); vals.resize(unique(vals.begin(), vals.end()) - vals.begin()); for (int i = 0; i < n; i++) { rl[i] = lower_bound(vals.begin(), vals.end(), rl[i]) - vals.begin(); rr[i] = lower_bound(vals.begin(), vals.end(), rr[i]) - vals.begin(); ranges.push_back({rl[i], rr[i], i}); } rl[n] = rr[n] = 1e9 + 42; for (int i = 0; i < (int)vals.size(); i++) insert(i, n, true); sort(ranges.begin(), ranges.end()); for (int i = 0; i < n; i++) { //cout << "doing range " << ranges[i].id << ' ' << ranges[i].rl << ' ' << ranges[i].rr << '\n'; jump[0][ranges[i].id] = query(ranges[i].rl, ranges[i].rr); //cout << "query is " << jump[0][ranges[i].id] << '\n'; if (jump[0][ranges[i].id] == -1) jump[0][ranges[i].id] = ranges[i].id; //cout << "inserting at " << ranges[i].rr << '\n'; insert(ranges[i].rr, ranges[i].id); //cout << "val at pos " << query(ranges[i].rr, ranges[i].rr) << '\n'; } for (int i = 1; i <= 19; i++) for (int j = 0; j < n; j++) jump[i][j] = jump[i - 1][jump[i - 1][j]]; for (int i = 0; i < q; i++) { int s, e; cin >> s >> e; s--, e--; if (s == e) { cout << "0\n"; continue; } if (rl[e] <= rr[s] && rr[s] <= rr[e]) { cout << "1\n"; continue; } if (rl[s] > rl[e]) { cout << "impossible\n"; continue; } int ans = 0; //cout << "start has " << rl[s] << ' ' << rr[s] << '\n'; //cout << "bef jump left is " << rl[e] << " right is " << rr[e] << '\n'; for (int bit = 19; bit >= 0; bit--) { int nxt = jump[bit][e]; if (rl[nxt] > rr[s]) { //cout << "nxt has " << rl[nxt] << ' ' << rr[nxt] << '\n'; //cout << "jumping of " << (1 << bit) << '\n'; ans += (1 << bit); e = nxt; } } //cout << "preans " << ans << '\n'; //cout << "bef end left is " << rl[e] << " right is " << rr[e] << '\n'; ans++; e = jump[0][e]; //cout << "last jump left is " << rl[e] << " right is " << rr[e] << '\n'; if (rl[e] <= rr[s]) { cout << ans + 1 << '\n'; } else { cout << "impossible\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...