Submission #1116311

#TimeUsernameProblemLanguageResultExecution timeMemory
1116311Zero_OPAbracadabra (CEOI22_abracadabra)C++14
100 / 100
433 ms48200 KiB
#include <bits/stdc++.h>

using namespace std;

const int MAX = 2e5 + 5;

int N, Q, p[MAX], q[MAX], nxt[MAX];
vector<pair<int, int>> queries[MAX];

struct fenwick_tree{
    int L;
    vector<int> bit, ar;
    fenwick_tree(int n) : bit(n + 1, 0), ar(n + 1, 0), L(31 - __builtin_clz(n)) {}

    void update(int i, int v){
        for(; i < (int)bit.size(); i += i & (-i)) bit[i] += v;
    }

    int query(int i){
        int sum = 0;
        for(; i > 0; i -= i & (-i)) sum += bit[i];
        return sum;
    }

    int walk_first_lower(int k){ //first lower
        int pos = 0;
        for(int i = L; i >= 0; --i){
            if(pos + (1 << i) < (int)bit.size() && bit[pos + (1 << i)] < k){
                k -= bit[pos + (1 << i)];
                pos += (1 << i);
            }
        }
        return pos;
    }
};

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);

#ifdef LOCAL
    freopen("task.inp", "r", stdin);
    freopen("task.out", "w", stdout);
#endif // LOCAL

    cin >> N >> Q;
    for(int i = 1; i <= N; ++i){
        cin >> p[i];
        q[p[i]] = i;
    }

    for(int i = 0; i < Q; ++i){
        int t, v;
        cin >> t >> v;
        queries[min(t, N)].emplace_back(v, i);
    }

    stack<int> st;
    for(int i = N; i >= 1; --i){
        while(!st.empty() && p[i] > p[st.top()]) st.pop();
        nxt[i] = (st.empty() ? N + 1 : st.top());
        st.push(i);
    }

    fenwick_tree ft(N);

    for(int i = 1; i <= N; i = nxt[i]){
        ft.update(p[i], nxt[i] - i);
    }

    auto get_kth = [&](int kth){
        int head = ft.walk_first_lower(kth) + 1;
        int sum_sizes = ft.query(head - 1);
        assert(sum_sizes < kth);
        return p[q[head] + kth - sum_sizes - 1];
    };

    bool demand = true;

    auto simulate = [&](){
        //info p[N/2]
        int head = ft.walk_first_lower(N / 2) + 1;
        int sum_sizes = ft.query(head);
        if(sum_sizes == N / 2) {
            demand = false;
            return; //[N/2] and [N/2+1] are in different blocks
        }

        //phase 1 : cut the left part
        int sum_previous_sizes = ft.query(head - 1);
        int current_block_size = sum_sizes - sum_previous_sizes;
        int position_head = q[head];
        int left_part_cut_size = N / 2 - sum_previous_sizes;
        ft.update(head, -current_block_size + left_part_cut_size);

        //phase 2 : divide the right part into some smaller blocks
        int new_head = p[q[head] + left_part_cut_size];
        int cur = N / 2;
        int old_bound = sum_sizes;

        int i;
        for(i = q[new_head]; cur + nxt[i] - i < old_bound; i = nxt[i]){
            ft.update(p[i], nxt[i] - i);
            cur += nxt[i] - i;
        }

        ft.update(p[i], old_bound - cur);
    };

    vector<int> ans(Q);
    for(int t = 0; t <= N; ++t){
        for(auto [kth, id] : queries[t])
            ans[id] = get_kth(kth);
        if(demand) simulate();
    }

    for(int i = 0; i < Q; ++i){
        cout << ans[i] << '\n';
    }

    return 0;
}

Compilation message (stderr)

Main.cpp: In constructor 'fenwick_tree::fenwick_tree(int)':
Main.cpp:12:22: warning: 'fenwick_tree::ar' will be initialized after [-Wreorder]
   12 |     vector<int> bit, ar;
      |                      ^~
Main.cpp:11:9: warning:   'int fenwick_tree::L' [-Wreorder]
   11 |     int L;
      |         ^
Main.cpp:13:5: warning:   when initialized here [-Wreorder]
   13 |     fenwick_tree(int n) : bit(n + 1, 0), ar(n + 1, 0), L(31 - __builtin_clz(n)) {}
      |     ^~~~~~~~~~~~
Main.cpp: In lambda function:
Main.cpp:91:13: warning: unused variable 'position_head' [-Wunused-variable]
   91 |         int position_head = q[head];
      |             ^~~~~~~~~~~~~
Main.cpp: In function 'int main()':
Main.cpp:111:18: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  111 |         for(auto [kth, id] : queries[t])
      |                  ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...