Submission #1350191

#TimeUsernameProblemLanguageResultExecution timeMemory
1350191ngtmanhIndex (COCI21_index)C++20
110 / 110
696 ms43484 KiB
#include <bits/stdc++.h>
using namespace std;

struct Wavelet_Tree
{
    int low, high;
    Wavelet_Tree *L = NULL, *R = NULL;
    vector <int> B;

    Wavelet_Tree() {}
    Wavelet_Tree(int *From, int *To, int x, int y)
    {
        low = x, high = y;
        if (low == high || From >= To) return;
        int mid = (low + high) / 2;
        auto F = [mid](int x)
        {
            return x <= mid;
        };
        B.reserve(To - From + 1);
        B.push_back(0);
        for (auto it = From; it != To; ++it)
            B.push_back(B.back() + F(*it));
        auto pivot = stable_partition(From, To, F);
        L = new Wavelet_Tree(From, pivot, low, mid);
        R = new Wavelet_Tree(pivot, To, mid + 1, high);
    }

    /// Phần tử nhỏ thứ k trong [l, r]
    int FindKth(int l, int r, int K)
    {
        if (l > r) return 0;
        if (low == high) return low;
        int cnt_left = B[r] - B[l - 1];
        if (K <= cnt_left) return L->FindKth(B[l - 1] + 1, B[r], K);
        return R->FindKth(l - B[l - 1], r - B[r], K - cnt_left);
    }

    /// số lượng phần tử trong [l, r] = K
    int Count(int l, int r, int K)
    {
        if (l > r || K < low || K > high) return 0;
        if (low == high) return r - l + 1;
        int mid = (low + high) / 2;
        if (K <= mid) return L->Count(B[l - 1] + 1, B[r], K);
        return R->Count(l - B[l - 1], r - B[r], K);
    }

    /// số lượng phần tử trong [l, r] <= K
    /// Count less than or equal
    int Count_LTE(int l, int r, int K)
    {
        if (l > r || K < low) return 0;
        if (high <= K) return r - l + 1;
        return L->Count_LTE(B[l - 1] + 1, B[r], K) + R->Count_LTE(l - B[l - 1], r - B[r], K);
    }

} wvl;
const int N = 2e5 + 4;
int n, a[N], MAX, q;

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

    cin >> n >> q;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    MAX = *max_element(a + 1, a + 1 + n);
    wvl = Wavelet_Tree(a + 1, a + n + 1, 1, MAX);

    while (q--)
    {
        int l, r;
        cin >> l >> r;
        int len = r - l + 1;
        int low = 0, high = len, ans = 0;
        while (low <= high)
        {
            int mid = (low + high) / 2;
            int cnt = len - wvl.Count_LTE(l , r , mid - 1);
            if (cnt >= mid)
            {
                ans = mid;
                low = mid + 1;
            }
            else
                high = mid - 1;
        }
        cout << ans << "\n";
    }
}

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...