Submission #1303892

#TimeUsernameProblemLanguageResultExecution timeMemory
1303892chaitanyamehtaCurtains (NOI23_curtains)C++20
0 / 100
0 ms568 KiB
#include <bits/stdc++.h> using namespace std; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<int> mx(n+2, 0); // mx[i] = max r among intervals with left == i for(int i=1;i<=n;i++) mx[i] = i-1; // default: cannot cover starting at i for(int i=0;i<m;i++){ int l, r; cin >> l >> r; if(l < 1) l = 1; if(l > n) continue; mx[l] = max(mx[l], r); } // Build sparse table on mx for range-maximum queries int LOG = 1; while((1<<LOG) <= n) ++LOG; vector<vector<int>> st(LOG, vector<int>(n+2)); for(int i=1;i<=n;i++) st[0][i] = mx[i]; for(int k=1;k<LOG;k++){ int len = 1<<(k-1); for(int i=1;i + (1<<k) - 1 <= n; i++){ st[k][i] = max(st[k-1][i], st[k-1][i+len]); } } auto rmq = [&](int l, int r)->int{ if(l > r) return l-1; // no valid interval -> return a "stuck" value int len = r - l + 1; int k = 31 - __builtin_clz(len); return max(st[k][l], st[k][r - (1<<k) + 1]); }; // Build binary-lifting table up[k][i] = farthest reach from i using <= 2^k intervals vector<vector<int>> up(LOG, vector<int>(n+2)); for(int i=1;i<=n;i++) up[0][i] = mx[i]; for(int k=1;k<LOG;k++){ for(int i=1;i<=n;i++){ int mid = up[k-1][i]; up[k][i] = rmq(i, mid); // max mx[j] for j in [i..mid] } } int q; cin >> q; while(q--){ int s,e; cin >> s >> e; if(s < 1) s = 1; if(e > n) e = n; if(s > e){ cout << "No\n"; continue; } // If no interval starting at s can cover s, impossible if(mx[s] < s){ cout << "No\n"; continue; } int pos = s; if(pos > e){ cout << "Yes\n"; continue; } // If already mx[s] >= e then covered by one or more intervals that start at s (maybe one) // We'll use binary lifting to jump as far as needed for(int k = LOG-1; k >= 0; --k){ int reach = up[k][pos]; if(reach < e){ // If reach did not advance, stuck -> impossible if(reach < pos){ pos = n+1; // force fail break; } pos = reach + 1; if(pos > e) break; } } bool ok = false; if(pos <= e){ // Need one final interval starting at pos to cover remaining part if(mx[pos] >= e) ok = true; else ok = false; } else { // pos > e => covered already ok = true; } cout << (ok ? "Yes\n" : "No\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...