Advertisement
volochai

D 773

Dec 11th, 2022
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.62 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #pragma GCC optimize("Ofast")
  4. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  5.  
  6. #define ll long long
  7. #define all(x) (x).begin(), (x).end()
  8. #define rall(x) (x).rbegin(), (x).rend()
  9. #define boost ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
  10. #define watch(x) cout << (#x) << " : " << x << '\n'
  11.  
  12. using namespace std;  
  13.  
  14. const int N = (int)3e5 + 128;
  15. int t[4 * N];
  16.  
  17. int n;
  18.  
  19. void build(int v, int tl, int tr) {
  20.     if (tl == tr) {
  21.         t[v] = 0; return;
  22.     }
  23.     int tm = (tl + tr) >> 1;
  24.     build(v << 1, tl, tm);
  25.     build(v << 1 | 1, tm + 1, tr);
  26.     t[v] = 0;
  27. }
  28.  
  29. void add(int pos, int val, int v, int tl, int tr) {
  30.     if (tl > pos || tr < pos)
  31.         return;
  32.     if (tl == tr) {
  33.         t[v] += val;
  34.         return;
  35.     }
  36.     int tm = (tl + tr) >> 1;
  37.     add(pos, val, v << 1, tl, tm);
  38.     add(pos, val, v << 1 | 1, tm + 1, tr);
  39.     t[v] = min(t[v << 1], t[v << 1 | 1]);
  40. }
  41.  
  42. void add(int pos, int val) { add(pos, val, 1, 0, n - 1); }
  43.  
  44. int get(int l, int r, int v, int tl, int tr) {
  45.     if (tl > r || tr < l)
  46.         return (int)2e9;
  47.     if (l <= tl && tr <= r)
  48.         return t[v];
  49.     int tm = (tl + tr) >> 1;
  50.     return min(get(l, r, v << 1, tl, tm),
  51.         get(l, r, v << 1 | 1, tm + 1, tr));
  52. }
  53.  
  54. int get(int l, int r) { return get(l, r, 1, 0, n - 1); }
  55.  
  56. int mx[4 * N];
  57.  
  58. void build(vector <int>& a, int v, int tl, int tr) {
  59.     if (tl == tr) {
  60.         mx[v] = a[tl]; return;
  61.     }
  62.     int tm = (tl + tr) >> 1;
  63.     build(a, v << 1, tl, tm);
  64.     build(a, v << 1 | 1, tm + 1, tr);
  65.     mx[v] = max(mx[v << 1], mx[v << 1 | 1]);
  66. }
  67.  
  68. int get_max(int l, int r, int v, int tl, int tr) {
  69.     if (tl > r || tr < l)
  70.         return -(int)2e9;
  71.     if (l <= tl && tr <= r)
  72.         return mx[v];
  73.     int tm = (tl + tr) >> 1;
  74.     return max(get_max(l, r, v << 1, tl, tm),
  75.         get_max(l, r, v << 1 | 1, tm + 1, tr));
  76. }
  77.  
  78.  
  79. int get_max(int l, int r) { return get_max(l, r, 1, 0, n - 1); }
  80.  
  81. void solve() {  
  82.     cin >> n;
  83.     vector <int> a(n);
  84.     for (auto& x : a)
  85.         cin >> x, x--;
  86.    
  87.     stack < pair<int, int> > st;
  88.     vector <int> fleft(n, -1), fright(n, n);
  89.  
  90.     for (int i = n - 1; i >= 0; i--) {
  91.         while (!st.empty() && a[i] > st.top().first) {
  92.             fleft[st.top().second] = i;
  93.             st.pop();
  94.         }
  95.         st.push({ a[i], i });
  96.     }
  97.  
  98.     while (!st.empty())
  99.         st.pop();
  100.  
  101.     for (int i = 0; i < n; i++) {
  102.         while (!st.empty() && a[i] > st.top().first) {
  103.             fright[st.top().second] = i;
  104.             st.pop();
  105.         }
  106.         st.push({ a[i], i });
  107.     }
  108.  
  109.     while (!st.empty())
  110.         st.pop();
  111.  
  112.     set < pair<int, int> > check;
  113.     for (int i = 0; i < n; i++)
  114.         check.insert({ fleft[i] + 1, fright[i] - 1 });
  115.  
  116.     int BLOCK = (int)sqrt(n) * 2;
  117.  
  118.     vector < pair<int, int> > query(all(check));
  119.     sort(all(query), [&BLOCK](const pair<int, int>& x, const pair<int, int>& y) -> bool {
  120.         if (x.first / BLOCK != y.first / BLOCK)
  121.             return x.first < y.first;
  122.         return x.second < y.second;
  123.     });  
  124.  
  125.     build(1, 0, n - 1);
  126.     build(a, 1, 0, n - 1);  
  127.  
  128.     assert(check.count({ 0, n - 1 }));
  129.  
  130.     int ans = 0;
  131.     int l = query[0].first, r = query[0].second;
  132.     for (int i = l; i <= r; i++)
  133.         add(a[i], +1);
  134.     ans = max(ans, (get(0, get_max(l, r)) > 0) * (r - l + 1));  
  135.  
  136.     for (int i = 1; i < (int)query.size(); i++) {
  137.         if (ans >= (query[i].second - query[i].first + 1))
  138.             continue;
  139.         while (l < query[i].first)
  140.             add(a[l++], -1);  
  141.         while (r < query[i].second)
  142.             add(a[++r], +1);  
  143.         while (l > query[i].first)
  144.             add(a[--l], +1);
  145.         while (r > query[i].second)
  146.             add(a[r--], -1);  
  147.         assert(l == query[i].first);
  148.         assert(r == query[i].second);
  149.         ans = max(ans, (get(0, get_max(l, r)) > 0) * (r - l + 1));
  150.     }
  151.  
  152.     cout << ans << '\n';
  153. }
  154.  
  155. signed main() {  
  156.     boost;
  157.     int t = 1;
  158.     cin >> t;
  159.     while (t--)
  160.         solve();
  161.     return 0;
  162. }
  163.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement