/ SeriousOJ /

Record Detail

Time Exceeded


  
# Status Time Cost Memory Cost
#1 Accepted 1ms 320.0 KiB
#2 Accepted 1ms 320.0 KiB
#3 Accepted 163ms 5.453 MiB
#4 Accepted 1ms 324.0 KiB
#5 Accepted 1ms 492.0 KiB
#6 Accepted 165ms 5.441 MiB
#7 Accepted 67ms 5.438 MiB
#8 Accepted 69ms 5.664 MiB
#9 Time Exceeded ≥2556ms ≥5.387 MiB
#10 Time Exceeded ≥2572ms ≥5.344 MiB

Code

#include <bits/stdc++.h>
using namespace std;

struct Query {
    int l, r, idx;
    Query(int left, int right, int index) : l(left), r(right), idx(index) {}
};

// Custom comparator for sorting queries in Mo's order
bool compareQueries(const Query &a, const Query &b) {
    static int blockSize = sqrt(2 * 1e5);  // √(max N)
    if (a.l / blockSize != b.l / blockSize)
        return a.l < b.l;
    return (a.l / blockSize % 2 == 0) ? (a.r < b.r) : (a.r > b.r);
}

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

    int N, Q;
    cin >> N >> Q;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) {
        cin >> A[i];
    }

    vector<Query> queries;
    for (int i = 0; i < Q; ++i) {
        int l, r;
        cin >> l >> r;
        queries.emplace_back(l - 1, r - 1, i); // Convert 1-based index to 0-based
    }

    // Sort queries based on Mo's algorithm ordering
    sort(queries.begin(), queries.end(), compareQueries);

    vector<int> answer(Q, -1);
    vector<int> freq(N + 1, 0); // Frequency of each element in the current range
    vector<int> candidates; // Stores elements with non-zero frequency in current range

    int currentL = 0, currentR = -1;

    auto add = [&](int pos) {
        int val = A[pos];
        if (++freq[val] == 1) candidates.push_back(val);
    };

    auto remove = [&](int pos) {
        int val = A[pos];
        if (--freq[val] == 0) {
            candidates.erase(std::remove(candidates.begin(), candidates.end(), val), candidates.end());
        }
    };

    for (const auto& q : queries) {
        int left = q.l;
        int right = q.r;
        int threshold = (right - left + 1) / 3;

        // Extend the range to [left, right]
        while (currentR < right) add(++currentR);
        while (currentR > right) remove(currentR--);
        while (currentL < left) remove(currentL++);
        while (currentL > left) add(--currentL);

        // Check for the smallest element meeting the frequency condition
        int minValue = INT_MAX;
        for (int candidate : candidates) {
            if (freq[candidate] > threshold) {
                minValue = min(minValue, candidate);
            }
        }

        answer[q.idx] = (minValue == INT_MAX) ? -1 : minValue;
    }

    // Output results for each query
    for (int i = 0; i < Q; ++i) {
        cout << answer[i] << '\n';
    }

    return 0;
}

Information

Submit By
Type
Submission
Problem
P1103 The Secret Garden of Numbers
Contest
Brain Booster #7
Language
C++17 (G++ 13.2.0)
Submit At
2024-11-05 16:12:27
Judged At
2024-11-11 02:28:02
Judged By
Score
40
Total Time
≥2572ms
Peak Memory
≥5.664 MiB