제출 #1226270

#제출 시각아이디문제언어결과실행 시간메모리
1226270spetrAbracadabra (CEOI22_abracadabra)C++20
100 / 100
577 ms55328 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long
const ll mmod = 998244353;  
#define vl vector<long long>
#define vll vector<vector<long long>>
#define pl pair<long long, long long>
#define vb vector<bool>

vl tree;
vl hranice;
vl nums;
ll velikost;

void update(ll l, ll L, ll R, ll c, ll i){
    if (L == R){
        tree[i] += c;
        return;
    }
    ll mid = (L + R) / 2;
    if (l <= mid) update(l, L, mid, c, 2*i + 1);
    else update(l, mid+1, R, c, 2*i + 2);
    tree[i] = tree[2*i + 1] + tree[2*i + 2];
}

ll secti(ll l, ll r, ll L, ll R, ll i){
    if (r < L || R < l) return 0;
    if (l <= L && R <= r) return tree[i];
    ll mid = (L + R) / 2;
    return secti(l, r, L, mid, 2*i + 1)
         + secti(l, r, mid+1, R, 2*i + 2);
}

ll target(ll t, ll i){
    ll L = 0, R = velikost - 1;
    ll pos = -1;
    while (L < R) {
        ll mid = (L + R) / 2;
        ll leftSum = tree[2*i + 1];
        if (leftSum < t) {
            t -= leftSum;
            pos = mid;
            i = 2*i + 2;
            L = mid + 1;
        } else {
            i = 2*i + 1;
            R = mid;
        }
    }
    return pos + 1;
}


void solve(ll l, ll r){
    ll i = l;
    while (i <= r){
        ll j = min(hranice[i], r+1);
        update(nums[i], 0, velikost-1, j - i, 0);
        i = j;
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ll n, q;
    cin >> n >> q;
    nums.resize(n);
    vl idx(n);
    for (ll i = 0; i < n; i++){
        ll num;
        cin >> num;
        num--;
        nums[i] = num;
        idx[num] = i;
    }

    for (velikost = 1; velikost < n; velikost *= 2);
    tree.resize(2*velikost-1, 0);
    hranice.resize(n, n);

    vl st;
    for (ll i = n-1; i >= 0; i--){
        while (!st.empty() && nums[st.back()] < nums[i]) st.pop_back();
        if (st.empty()){hranice[i] = n;} else hranice[i] = st.back(); 
        st.push_back(i);
    }

    vector<vector<pl>> queries(n+1);
    for (ll i = 0; i < q; i++){
        ll t, b;
        cin >> t >> b;
        queries[min(t, n)].push_back({b-1, i});
    }
    vl ans(q);

    for (auto &p : queries[0]){
        ans[p.second] = nums[p.first];
    }

    solve(0, n/2 - 1);
    solve(n/2, n-1);

    for (ll i = 1; i <= n; i++){

        for (auto p : queries[i]){
            ll pos = p.first;
            ll delka_bloku = target(pos+1, 0);
            ll pref = secti(0, delka_bloku-1, 0, velikost-1, 0);
            ll presah = pos - pref;
            ans[p.second] = nums[idx[delka_bloku] + presah];
        }
        ll delka_pul = target(n/2 + 1, 0);
        ll pref = secti(0, delka_pul-1, 0, velikost-1, 0);
        ll L = (n/2 - pref) + idx[delka_pul];
        ll R = (secti(0, delka_pul, 0, velikost-1, 0) - pref - 1) + idx[delka_pul];
        solve(L, R);
        update(delka_pul, 0, velikost-1, -(R - L + 1), 0);
    }

    for (ll i = 0; i < q; i++){
        cout << ans[i] + 1 << "\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...