Advertisement
erek1e

POI Task Salad Bar

Jun 25th, 2023
887
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.38 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <set>
  4. #include <string>
  5. #include <algorithm>
  6. #include <cassert>
  7.  
  8. using namespace std;
  9.  
  10. struct Segment {
  11.     int l, r;
  12.     pair<int, int> mx; // largest on segment: (value, index)
  13.     Segment() {}
  14.     Segment(int i, int v): l(i), r(i), mx(v, i) {}
  15.     bool operator < (const Segment &s2) const {
  16.         return pair<int, int>{l, r} < pair<int, int>{s2.l, s2.r};
  17.     }
  18.     Segment operator + (const Segment &s2) const { // merge two adjacent segments
  19.         assert(r+1 == s2.l);
  20.         Segment s;
  21.         s.l = l, s.r = s2.r;
  22.         s.mx = max(mx, s2.mx);
  23.         return s;
  24.     }
  25. };
  26.  
  27. int main() {
  28.     int n; string s;
  29.     cin >> n >> s;
  30.     bool allJ = true;
  31.     for (char c : s) {
  32.         if (c == 'p') allJ = false;
  33.     }
  34.     if (allJ) {
  35.         cout << "0\n";
  36.         return 0;
  37.     }
  38.  
  39.     int ans = 1;
  40.     vector<int> p(1+n);
  41.     for (int i = 1; i <= n; ++i) p[i] = p[i-1] + (s[i-1] == 'p' ? +1 : -1);
  42.  
  43.     set<Segment> st; // segments of added values
  44.     vector<pair<int, int>> bySize;
  45.     for (int i = 0; i <= n; ++i) bySize.emplace_back(p[i], i);
  46.     sort(bySize.begin(), bySize.end());
  47.     while (!bySize.empty()) {
  48.         auto [v, i] = bySize.back();
  49.         bySize.pop_back();
  50.  
  51.         // add into set of segments
  52.         Segment seg(i, v);
  53.         auto it = st.lower_bound(seg);
  54.         if (it != st.end() && it->l == i+1) { // merge with next segment
  55.             /*
  56.             consider index i as the element before the start of the substring, with some index k being the end (i, k]
  57.             all indices j between i and the end k of the substring must have p[i] <= p[j] <= p[k]
  58.             maxK = it->r, since next j does not satisfy p[i] <= p[j]
  59.             the other constraint is p[j] <= p[k], so p[k] must be the maximum encountered so far after p[i]
  60.             the last of these will simply be the (rightmost) largest value in the range [i, maxK]
  61.             */
  62.             ans = max(ans, it->mx.second-i);
  63.            
  64.             // now merge
  65.             seg = seg + *it;
  66.             it = st.erase(it);
  67.         }
  68.         if (it != st.begin()) {
  69.             --it;
  70.             if (it->r == i-1) { // merge with previous segment
  71.                 seg = *it + seg;
  72.                 st.erase(it);
  73.             }
  74.         }
  75.         st.insert(seg).first;
  76.     }
  77.     cout << ans << endl;
  78.     return 0;
  79. }
  80.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement