CSES - Aalto Competitive Programming 2024 - wk4 - Mon - Results
Submission details
Task:Moon landing
Sender:eyong002
Submission time:2024-09-24 17:17:16 +0300
Language:C++ (C++20)
Status:COMPILE ERROR

Compiler report

input/code.cpp: In constructor 'SegmentTree::SegmentTree(int, bool)':
input/code.cpp:15:40: error: 'INT_MIN' was not declared in this scope
   15 |         tree.resize(4 * n, isMaxTree ? INT_MIN : INT_MAX);  // Use INT_MIN for max, INT_MAX for min
      |                                        ^~~~~~~
input/code.cpp:4:1: note: 'INT_MIN' is defined in header '<climits>'; did you forget to '#include <climits>'?
    3 | #include <algorithm>
  +++ |+#include <climits>
    4 | using namespace std;
input/code.cpp:15:50: error: 'INT_MAX' was not declared in this scope
   15 |         tree.resize(4 * n, isMaxTree ? INT_MIN : INT_MAX);  // Use INT_MIN for max, INT_MAX for min
      |                                                  ^~~~~~~
input/code.cpp:15:50: note: 'INT_MAX' is defined in header '<climits>'; did you forget to '#include <climits>'?
input/code.cpp: In member function 'int SegmentTree::query(int, int, int, int, int)':
input/code.cpp:35:32: error: 'INT_MIN' was not declared in th...

Code

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Segment Tree for Range Minimum and Maximum Queries
class SegmentTree {
public:
    vector<int> tree;
    int size;
    
    // Initialize the segment tree
    SegmentTree(int n, bool isMaxTree) {
        size = n;
        tree.resize(4 * n, isMaxTree ? INT_MIN : INT_MAX);  // Use INT_MIN for max, INT_MAX for min
        this->isMaxTree = isMaxTree;
    }
    
    // Build the segment tree
    void build(const vector<int>& a, int node, int start, int end) {
        if (start == end) {
            tree[node] = a[start];
        } else {
            int mid = (start + end) / 2;
            build(a, 2 * node + 1, start, mid);
            build(a, 2 * node + 2, mid + 1, end);
            tree[node] = isMaxTree ? max(tree[2 * node + 1], tree[2 * node + 2])
                                   : min(tree[2 * node + 1], tree[2 * node + 2]);
        }
    }
    
    // Query the range [L, R]
    int query(int node, int start, int end, int L, int R) {
        if (R < start || end < L) {
            return isMaxTree ? INT_MIN : INT_MAX;  // Return appropriate identity value
        }
        if (L <= start && end <= R) {
            return tree[node];
        }
        int mid = (start + end) / 2;
        int leftQuery = query(2 * node + 1, start, mid, L, R);
        int rightQuery = query(2 * node + 2, mid + 1, end, L, R);
        return isMaxTree ? max(leftQuery, rightQuery) : min(leftQuery, rightQuery);
    }
    
private:
    bool isMaxTree;  // Determines if the segment tree is for max or min
};

int main() {
    int n, x;
    cin >> n >> x;
    
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    
    // Build a segment tree for range maximum queries and range minimum queries
    SegmentTree maxTree(n, true);   // Max segment tree
    SegmentTree minTree(n, false);  // Min segment tree
    
    // Build both trees based on the input array
    maxTree.build(a, 0, 0, n - 1);
    minTree.build(a, 0, 0, n - 1);
    
    int left = 0, bestLength = 0, bestStart = 0;
    
    // Sliding window approach
    for (int right = 0; right < n; ++right) {
        while (true) {
            // Query the current window [left, right] for max and min
            int maxVal = maxTree.query(0, 0, n - 1, left, right);
            int minVal = minTree.query(0, 0, n - 1, left, right);
            
            if (maxVal - minVal <= x) {
                // Valid window, update the best result if necessary
                if (right - left + 1 > bestLength) {
                    bestLength = right - left + 1;
                    bestStart = left;
                }
                break;  // This window is valid, no need to shrink
            } else {
                // Shrink the window from the left
                ++left;
            }
        }
    }
    
    // Output the result (1-based index and the length of the best subarray)
    cout << bestStart + 1 << " " << bestLength << endl;
    
    return 0;
}