/ SeriousOJ /

Record Detail

Time Exceeded


  
# Status Time Cost Memory Cost
#1 Accepted 1ms 532.0 KiB
#2 Accepted 1ms 320.0 KiB
#3 Accepted 544ms 5.395 MiB
#4 Accepted 1ms 532.0 KiB
#5 Accepted 1ms 532.0 KiB
#6 Accepted 535ms 5.391 MiB
#7 Accepted 69ms 5.375 MiB
#8 Accepted 71ms 5.566 MiB
#9 Time Exceeded ≥2599ms ≥6.336 MiB
#10 Time Exceeded ≥2600ms ≥5.773 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
    unordered_map<int, int> candidateCount; // Maps value to how many times it appears in the current range
    int currentL = 0, currentR = -1;

    auto add = [&](int pos) {
        int val = A[pos];
        freq[val]++;
        candidateCount[val]++;
    };

    auto remove = [&](int pos) {
        int val = A[pos];
        freq[val]--;
        if (freq[val] == 0) {
            candidateCount.erase(val);
        } else {
            candidateCount[val]--;
        }
    };

    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 (const auto& [value, count] : candidateCount) {
            if (count > threshold) {
                minValue = min(minValue, value);
            }
        }

        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:14:21
Judged At
2024-11-05 16:14:21
Judged By
Score
40
Total Time
≥2600ms
Peak Memory
≥6.336 MiB