sudama_bera

Untitled

Oct 22nd, 2026
19
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.51 KB | Source Code | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <unordered_map>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. // Standard Range Minimum Query (RMQ) Segment Tree
  9. struct SegTree {
  10.     int n;
  11.     vector<long long> tree;
  12.    
  13.     SegTree(const vector<long long>& arr) {
  14.         n = arr.size();
  15.         tree.assign(4 * n, 1e18);
  16.         build(arr, 1, 0, n - 1);
  17.     }
  18.    
  19.     void build(const vector<long long>& arr, int node, int start, int end) {
  20.         if (start == end) {
  21.             tree[node] = arr[start];
  22.             return;
  23.         }
  24.         int mid = start + (end - start) / 2;
  25.         build(arr, 2 * node, start, mid);
  26.         build(arr, 2 * node + 1, mid + 1, end);
  27.         tree[node] = min(tree[2 * node], tree[2 * node + 1]);
  28.     }
  29.    
  30.     long long query(int node, int start, int end, int L, int R) {
  31.         if (R < start || end < L) return 1e18;
  32.         if (L <= start && end <= R) return tree[node];
  33.        
  34.         int mid = start + (end - start) / 2;
  35.         long long left_min = query(2 * node, start, mid, L, R);
  36.         long long right_min = query(2 * node + 1, mid + 1, end, L, R);
  37.         return min(left_min, right_min);
  38.     }
  39.    
  40.     long long query(int L, int R) {
  41.         if (L > R) return 1e18;
  42.         return query(1, 0, n - 1, L, R);
  43.     }
  44. };
  45.  
  46. long long getMaxSubarraySumWithSegTree(const vector<long long>& arr) {
  47.     int n = arr.size();
  48.    
  49.     // 1-indexed prefix sums
  50.     vector<long long> prefix(n + 1, 0);
  51.     for (int i = 0; i < n; ++i) {
  52.         prefix[i + 1] = prefix[i] + arr[i];
  53.     }
  54.    
  55.     // Build RMQ Segment tree over the prefix sums
  56.     SegTree st(prefix);
  57.  
  58.     unordered_map<long long, int> last_seen, prev_seen, prev2_seen;
  59.    
  60.     // Track highest 2nd-to-last occurrences
  61.     int p1 = -1, p2 = -1;
  62.     long long val1 = 4e18, val2 = 4e18;
  63.    
  64.     // Track highest 3rd-to-last occurrence
  65.     int p3 = -1;
  66.    
  67.     long long max_sum = -1e18;
  68.     bool found_valid = false;
  69.  
  70.     for (int R = 0; R < n; ++R) {
  71.         long long x = arr[R];
  72.        
  73.         if (!last_seen.count(x)) {
  74.             last_seen[x] = -1;
  75.             prev_seen[x] = -1;
  76.             prev2_seen[x] = -1;
  77.         }
  78.        
  79.         prev2_seen[x] = prev_seen[x];
  80.         prev_seen[x] = last_seen[x];
  81.         last_seen[x] = R;
  82.        
  83.         p3 = max(p3, prev2_seen[x]);
  84.        
  85.         int new_p = prev_seen[x];
  86.         if (new_p > -1) {
  87.             if (x == val1) {
  88.                 p1 = new_p;
  89.             } else if (x == val2) {
  90.                 p2 = new_p;
  91.                 if (p2 > p1) {
  92.                     swap(p1, p2);
  93.                     swap(val1, val2);
  94.                 }
  95.             } else {
  96.                 if (new_p > p1) {
  97.                     p2 = p1;
  98.                     val2 = val1;
  99.                     p1 = new_p;
  100.                     val1 = x;
  101.                 } else if (new_p > p2) {
  102.                     p2 = new_p;
  103.                     val2 = x;
  104.                 }
  105.             }
  106.         }
  107.        
  108.         // The valid window of prefix indices for starting bound L
  109.         int W_left = max(p2, p3) + 1;
  110.         int W_right = p1;
  111.        
  112.         if (W_left <= W_right && p1 != -1) {
  113.             // O(log N) Range Minimum Query
  114.             long long min_prefix = st.query(W_left, W_right);
  115.            
  116.             long long current_sum = prefix[R + 1] - min_prefix;
  117.             max_sum = max(max_sum, current_sum);
  118.             found_valid = true;
  119.         }
  120.     }
  121.    
  122.     if (!found_valid) return -1e18;
  123.     return max_sum;
  124. }
Advertisement
Add Comment
Please, Sign In to add comment