Submission #1313079

#TimeUsernameProblemLanguageResultExecution timeMemory
1313079samarthkulkarniCurtains (NOI23_curtains)C++20
0 / 100
7 ms496 KiB
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

const int N = 5e5+10;
vector<int> st[N];
vector<pair<int,int>> qw[N];
int mx[N<<2], mn[N<<2];
int lzy[N<<2];
int seg_n;

// Completely inline everything - no function calls
inline void solve() {
    int n, m, q;
    scanf("%d%d%d", &n, &m, &q);  // scanf is faster than cin for large input
    
    seg_n = n + 2;
    memset(mx, -1, sizeof(int) * (seg_n << 2));
    memset(mn, -1, sizeof(int) * (seg_n << 2));
    
    for (int i = 0; i < m; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        st[r].push_back(l);
    }
    
    for (int i = 0; i < q; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        qw[r].push_back({l, i});
    }
    
    for (int i = 1; i <= n; i++) {
        sort(st[i].begin(), st[i].end(), greater<int>());
        sort(qw[i].begin(), qw[i].end(), greater<pair<int,int>>());
    }
    
    vector<int> res(q);
    
    for (int i = 1; i <= n; i++) {
        int j = 0;
        int st_sz = st[i].size();
        
        for (auto& [ql, e] : qw[i]) {
            while (j < st_sz && st[i][j] >= ql) {
                int pos = st[i][j];
                
                // Inline point update
                {
                    int id = 1, l = 0, r = seg_n - 1;
                    static int path[20];
                    int path_len = 0;
                    
                    while (l < r) {
                        if (lzy[id]) {
                            mx[id] = mn[id] = lzy[id];
                            lzy[id<<1] = lzy[id];
                            lzy[id<<1|1] = lzy[id];
                            lzy[id] = 0;
                        }
                        path[path_len++] = id;
                        int mid = (l + r) >> 1;
                        if (pos <= mid) { id = id<<1; r = mid; }
                        else { id = id<<1|1; l = mid+1; }
                    }
                    if (lzy[id]) { mx[id] = mn[id] = lzy[id]; lzy[id] = 0; }
                    mx[id] = mn[id] = i;
                    
                    while (path_len--) {
                        id = path[path_len];
                        int left = id<<1, right = id<<1|1;
                        int lmx = lzy[left] ? lzy[left] : mx[left];
                        int lmn = lzy[left] ? lzy[left] : mn[left];
                        int rmx = lzy[right] ? lzy[right] : mx[right];
                        int rmn = lzy[right] ? lzy[right] : mn[right];
                        mx[id] = max(lmx, rmx);
                        mn[id] = min(lmn, rmn);
                    }
                }
                
                // Inline range update (only if pos > 1)
                if (pos > 1) {
                    static int stk[40];
                    int top = 0;
                    stk[top++] = 1;
                    stk[top++] = 0;
                    stk[top++] = seg_n - 1;
                    
                    while (top) {
                        int r = stk[--top];
                        int l = stk[--top];
                        int id = stk[--top];
                        
                        if (lzy[id]) {
                            mx[id] = mn[id] = lzy[id];
                            if (l != r) {
                                lzy[id<<1] = lzy[id];
                                lzy[id<<1|1] = lzy[id];
                            }
                            lzy[id] = 0;
                        }
                        
                        if (mx[id] < pos - 1 || 1 > r || pos - 1 < l) continue;
                        
                        if (1 <= l && pos - 1 >= r && mn[id] >= pos - 1) {
                            mx[id] = mn[id] = i;
                            if (l != r) {
                                lzy[id<<1] = i;
                                lzy[id<<1|1] = i;
                            }
                            continue;
                        }
                        
                        if (l == r) continue;
                        
                        int mid = (l + r) >> 1;
                        
                        // Push to stack in reverse order
                        if (pos - 1 > mid) {
                            int rmx = lzy[id<<1|1] ? lzy[id<<1|1] : mx[id<<1|1];
                            if (rmx >= pos - 1) {
                                stk[top++] = id<<1|1;
                                stk[top++] = mid + 1;
                                stk[top++] = r;
                            }
                        }
                        if (1 <= mid) {
                            int lmx = lzy[id<<1] ? lzy[id<<1] : mx[id<<1];
                            if (lmx >= pos - 1) {
                                stk[top++] = id<<1;
                                stk[top++] = l;
                                stk[top++] = mid;
                            }
                        }
                        
                        // Update current node after children will be processed
                        int left = id<<1, right = id<<1|1;
                        int lmx = lzy[left] ? lzy[left] : mx[left];
                        int lmn = lzy[left] ? lzy[left] : mn[left];
                        int rmx = lzy[right] ? lzy[right] : mx[right];
                        int rmn = lzy[right] ? lzy[right] : mn[right];
                        mx[id] = max(lmx, rmx);
                        mn[id] = min(lmn, rmn);
                    }
                }
                j++;
            }
            
            // Inline query
            {
                int id = 1, l = 0, r = seg_n - 1;
                while (l < r) {
                    if (lzy[id]) {
                        mx[id] = mn[id] = lzy[id];
                        lzy[id<<1] = lzy[id];
                        lzy[id<<1|1] = lzy[id];
                        lzy[id] = 0;
                    }
                    int mid = (l + r) >> 1;
                    if (ql <= mid) { id = id<<1; r = mid; }
                    else { id = id<<1|1; l = mid+1; }
                }
                res[e] = ((lzy[id] ? lzy[id] : mx[id]) == i);
            }
        }
        
        // Process remaining curtains
        while (j < st_sz) {
            int pos = st[i][j];
            
            // Same point update as above
            {
                int id = 1, l = 0, r = seg_n - 1;
                static int path[20];
                int path_len = 0;
                
                while (l < r) {
                    if (lzy[id]) {
                        mx[id] = mn[id] = lzy[id];
                        lzy[id<<1] = lzy[id];
                        lzy[id<<1|1] = lzy[id];
                        lzy[id] = 0;
                    }
                    path[path_len++] = id;
                    int mid = (l + r) >> 1;
                    if (pos <= mid) { id = id<<1; r = mid; }
                    else { id = id<<1|1; l = mid+1; }
                }
                if (lzy[id]) { mx[id] = mn[id] = lzy[id]; lzy[id] = 0; }
                mx[id] = mn[id] = i;
                
                while (path_len--) {
                    id = path[path_len];
                    int left = id<<1, right = id<<1|1;
                    int lmx = lzy[left] ? lzy[left] : mx[left];
                    int lmn = lzy[left] ? lzy[left] : mn[left];
                    int rmx = lzy[right] ? lzy[right] : mx[right];
                    int rmn = lzy[right] ? lzy[right] : mn[right];
                    mx[id] = max(lmx, rmx);
                    mn[id] = min(lmn, rmn);
                }
            }
            
            // Same range update
            if (pos > 1) {
                static int stk[40];
                int top = 0;
                stk[top++] = 1;
                stk[top++] = 0;
                stk[top++] = seg_n - 1;
                
                while (top) {
                    int r = stk[--top];
                    int l = stk[--top];
                    int id = stk[--top];
                    
                    if (lzy[id]) {
                        mx[id] = mn[id] = lzy[id];
                        if (l != r) {
                            lzy[id<<1] = lzy[id];
                            lzy[id<<1|1] = lzy[id];
                        }
                        lzy[id] = 0;
                    }
                    
                    if (mx[id] < pos - 1 || 1 > r || pos - 1 < l) continue;
                    
                    if (1 <= l && pos - 1 >= r && mn[id] >= pos - 1) {
                        mx[id] = mn[id] = i;
                        if (l != r) {
                            lzy[id<<1] = i;
                            lzy[id<<1|1] = i;
                        }
                        continue;
                    }
                    
                    if (l == r) continue;
                    
                    int mid = (l + r) >> 1;
                    
                    if (pos - 1 > mid) {
                        int rmx = lzy[id<<1|1] ? lzy[id<<1|1] : mx[id<<1|1];
                        if (rmx >= pos - 1) {
                            stk[top++] = id<<1|1;
                            stk[top++] = mid + 1;
                            stk[top++] = r;
                        }
                    }
                    if (1 <= mid) {
                        int lmx = lzy[id<<1] ? lzy[id<<1] : mx[id<<1];
                        if (lmx >= pos - 1) {
                            stk[top++] = id<<1;
                            stk[top++] = l;
                            stk[top++] = mid;
                        }
                    }
                    
                    int left = id<<1, right = id<<1|1;
                    int lmx = lzy[left] ? lzy[left] : mx[left];
                    int lmn = lzy[left] ? lzy[left] : mn[left];
                    int rmx = lzy[right] ? lzy[right] : mx[right];
                    int rmn = lzy[right] ? lzy[right] : mn[right];
                    mx[id] = max(lmx, rmx);
                    mn[id] = min(lmn, rmn);
                }
            }
            j++;
        }
    }
    
    for (int i = 0; i < q; i++) {
        puts(res[i] ? "YES" : "NO");  // puts is faster than cout
    }
}

int main() {
    solve();
    return 0;
}

Compilation message (stderr)

curtains.cpp: In function 'void solve()':
curtains.cpp:17:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   17 |     scanf("%d%d%d", &n, &m, &q);  // scanf is faster than cin for large input
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~
curtains.cpp:25:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   25 |         scanf("%d%d", &l, &r);
      |         ~~~~~^~~~~~~~~~~~~~~~
curtains.cpp:31:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   31 |         scanf("%d%d", &l, &r);
      |         ~~~~~^~~~~~~~~~~~~~~~
#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...