// o3 code
#include <bits/stdc++.h>
using namespace std;
 
// We'll use 1-indexed arrays for machines and tasks.
 
// Data structure for segment tree (with lazy propagation)
// Each leaf corresponds to one machine’s "last-run" value (an integer in [0,m]).
// Our segment tree supports range updates (setting a whole interval to a given value)
// and range queries: we want to “collect” contiguous blocks of uniform value.
 
struct Node {
    int l, r;
    bool uniform; // true if the entire segment is set to a single value
    int val;     // the value if uniform (the "last-run" value)
};
 
// Global segment tree array.
vector<Node> segTree;
int n; // number of machines; will be set in main
 
// Build the segment tree over [l, r] (machine indices)
void build(int idx, int l, int r) {
    segTree[idx].l = l;
    segTree[idx].r = r;
    segTree[idx].uniform = true;
    segTree[idx].val = 0;  // initially no machine has been run
    if(l < r){
        int mid = (l + r) / 2;
        build(idx*2, l, mid);
        build(idx*2+1, mid+1, r);
    }
}
 
// Push down lazy update: if current node is uniform, propagate to children.
void pushDown(int idx) {
    if(!segTree[idx].uniform) return; // nothing to push
    if(segTree[idx].l == segTree[idx].r) return; // leaf, nothing to do
    int val = segTree[idx].val;
    // Set children uniformly to this value
    segTree[idx*2].uniform = true;
    segTree[idx*2].val = val;
    segTree[idx*2+1].uniform = true;
    segTree[idx*2+1].val = val;
}
 
// Range update: set all machines in [L, R] to new_val.
void updateRange(int idx, int L, int R, int new_val) {
    int l = segTree[idx].l, r = segTree[idx].r;
    if(R < l || r < L) return; // no overlap
    if(L <= l && r <= R) {
        segTree[idx].uniform = true;
        segTree[idx].val = new_val;
        return;
    }
    // Otherwise, push down the lazy value (if any)
    pushDown(idx);
    // Recurse
    updateRange(idx*2, L, R, new_val);
    updateRange(idx*2+1, L, R, new_val);
    // After update, check if children are uniform and equal.
    if(segTree[idx*2].uniform && segTree[idx*2+1].uniform &&
       segTree[idx*2].val == segTree[idx*2+1].val) {
        segTree[idx].uniform = true;
        segTree[idx].val = segTree[idx*2].val;
    } else {
        segTree[idx].uniform = false;
    }
}
 
// We want to query the range [L,R] and return a vector of pairs (p, count)
// where the interval [L,R] is partitioned into contiguous blocks that are uniform,
// each with value p (the "last-run" value) and block length = count.
 
void queryRange(int idx, int L, int R, vector<pair<int,int>> &res) {
    int l = segTree[idx].l, r = segTree[idx].r;
    if(R < l || r < L) return; // no overlap
    if(L <= l && r <= R && segTree[idx].uniform) {
        // Entire segment is uniform.
        res.push_back({segTree[idx].val, r - l + 1});
        return;
    }
    // Otherwise, push down and combine children.
    pushDown(idx);
    queryRange(idx*2, L, R, res);
    queryRange(idx*2+1, L, R, res);
}
 
// To merge contiguous blocks in the result vector.
void mergeResult(vector<pair<int,int>> &v) {
    if(v.empty()) return;
    vector<pair<int,int>> tmp;
    tmp.push_back(v[0]);
    for (size_t i=1; i<v.size(); i++){
        if(v[i].first == tmp.back().first)
            tmp.back().second += v[i].second;
        else
            tmp.push_back(v[i]);
    }
    v.swap(tmp);
}
 
// Main
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    int m, q;
    cin >> n >> m >> q;
    // tasks: store as 1-indexed arrays. For task i (1 <= i <= m), we have:
    // l[i] and r[i]
    vector<int> taskL(m+1), taskR(m+1);
    for (int i = 1; i <= m; i++){
        cin >> taskL[i] >> taskR[i];
    }
 
    // Precompute D[0..m]: D[i] = total number of machine runs in tasks 1..i.
    // Let D[0]=0.
    vector<long long> D(m+1,0);
    for (int i = 1; i <= m; i++){
        long long runs = (long long)taskR[i] - taskL[i] + 1;
        D[i] = D[i-1] + runs;
    }
 
    // Allocate segment tree. For n machines, we need up to 4*n nodes.
    segTree.resize(4 * (n + 1));
    build(1, 1, n);
 
    // We'll accumulate frequencies of "gap" values.
    // Each time a machine j is updated in a task i (if it had a previous run in task p != 0),
    // we add an event with gap = (D[i-1]-D[p-1]) - (taskL[i] - taskL[p]) - 1.
    // We sum the counts for each gap.
    unordered_map<long long, long long> freq;
    freq.reserve(m*2);
 
    // Process tasks in order.
    for (int i = 1; i <= m; i++){
        int L = taskL[i], R = taskR[i];
        vector<pair<int,int>> queryRes;
        queryRange(1, L, R, queryRes);
        mergeResult(queryRes);
        // For every contiguous block in [L,R] with uniform last-run value p,
        // if p != 0 then for all machines in that block, an inspection is needed now.
        for (auto &pcount : queryRes) {
            int p = pcount.first;
            int cnt = pcount.second;
            if(p != 0){
                // Compute gap = (D[i-1]-D[p-1]) - (taskL[i] - taskL[p]) - 1.
                // Note: taskL[p] is defined because p>=1.
                long long gap = (D[i-1] - D[p-1]) - ((long long)taskL[i] - taskL[p]) - 1;
                freq[gap] += cnt;
            }
        }
        // Now update machines in [L,R]: set their last-run value to i.
        updateRange(1, L, R, i);
    }
 
    // At this point, the total number of inspections (if safety value s=0)
    // equals the sum over all events, i.e. total frequency.
    // For a candidate safety value s, we need to count only those events
    // with gap >= s.
    // We now “compress” the frequency table into a sorted vector.
    vector<pair<long long,long long>> events;
    events.reserve(freq.size());
    for (auto &pr : freq) {
        events.push_back({pr.first, pr.second});
    }
    sort(events.begin(), events.end());
 
    // Build suffix sums: for each index i in events, let suff[i] = sum_{j >= i} events[j].second.
    int k = events.size();
    vector<long long> suff(k+1, 0);
    for (int i = k-1; i >= 0; i--){
        suff[i] = suff[i+1] + events[i].second;
    }
 
    // Answer the queries.
    // We read q candidate safety values s, and for each, output
    // the number of events (inspections) that happen if safety value = s.
    // (i.e. count of events with gap >= s)
    vector<long long> ans(q, 0);
    for (int i = 0; i < q; i++){
        long long sVal;
        cin >> sVal;
        // Binary search in events for the first event with gap >= sVal.
        int lo = 0, hi = k;
        while(lo < hi){
            int mid = (lo + hi) / 2;
            if(events[mid].first >= sVal) hi = mid;
            else lo = mid + 1;
        }
        long long tot = (lo < k ? suff[lo] : 0LL);
        ans[i] = tot;
    }
 
    // Output answers in one line.
    for (int i = 0; i < q; i++){
        cout << ans[i] << (i+1==q? "\n" : " ");
    }
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |