Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #pragma GCC optimize("Ofast")
- #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
- #define ll long long
- #define all(x) (x).begin(), (x).end()
- #define rall(x) (x).rbegin(), (x).rend()
- #define boost ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
- #define watch(x) cout << (#x) << " : " << x << '\n'
- using namespace std;
- const int N = (int)3e5 + 128;
- int t[4 * N];
- int n;
- void build(int v, int tl, int tr) {
- if (tl == tr) {
- t[v] = 0; return;
- }
- int tm = (tl + tr) >> 1;
- build(v << 1, tl, tm);
- build(v << 1 | 1, tm + 1, tr);
- t[v] = 0;
- }
- void add(int pos, int val, int v, int tl, int tr) {
- if (tl > pos || tr < pos)
- return;
- if (tl == tr) {
- t[v] += val;
- return;
- }
- int tm = (tl + tr) >> 1;
- add(pos, val, v << 1, tl, tm);
- add(pos, val, v << 1 | 1, tm + 1, tr);
- t[v] = min(t[v << 1], t[v << 1 | 1]);
- }
- void add(int pos, int val) { add(pos, val, 1, 0, n - 1); }
- int get(int l, int r, int v, int tl, int tr) {
- if (tl > r || tr < l)
- return (int)2e9;
- if (l <= tl && tr <= r)
- return t[v];
- int tm = (tl + tr) >> 1;
- return min(get(l, r, v << 1, tl, tm),
- get(l, r, v << 1 | 1, tm + 1, tr));
- }
- int get(int l, int r) { return get(l, r, 1, 0, n - 1); }
- int mx[4 * N];
- void build(vector <int>& a, int v, int tl, int tr) {
- if (tl == tr) {
- mx[v] = a[tl]; return;
- }
- int tm = (tl + tr) >> 1;
- build(a, v << 1, tl, tm);
- build(a, v << 1 | 1, tm + 1, tr);
- mx[v] = max(mx[v << 1], mx[v << 1 | 1]);
- }
- int get_max(int l, int r, int v, int tl, int tr) {
- if (tl > r || tr < l)
- return -(int)2e9;
- if (l <= tl && tr <= r)
- return mx[v];
- int tm = (tl + tr) >> 1;
- return max(get_max(l, r, v << 1, tl, tm),
- get_max(l, r, v << 1 | 1, tm + 1, tr));
- }
- int get_max(int l, int r) { return get_max(l, r, 1, 0, n - 1); }
- void solve() {
- cin >> n;
- vector <int> a(n);
- for (auto& x : a)
- cin >> x, x--;
- stack < pair<int, int> > st;
- vector <int> fleft(n, -1), fright(n, n);
- for (int i = n - 1; i >= 0; i--) {
- while (!st.empty() && a[i] > st.top().first) {
- fleft[st.top().second] = i;
- st.pop();
- }
- st.push({ a[i], i });
- }
- while (!st.empty())
- st.pop();
- for (int i = 0; i < n; i++) {
- while (!st.empty() && a[i] > st.top().first) {
- fright[st.top().second] = i;
- st.pop();
- }
- st.push({ a[i], i });
- }
- while (!st.empty())
- st.pop();
- set < pair<int, int> > check;
- for (int i = 0; i < n; i++)
- check.insert({ fleft[i] + 1, fright[i] - 1 });
- int BLOCK = (int)sqrt(n) * 2;
- vector < pair<int, int> > query(all(check));
- sort(all(query), [&BLOCK](const pair<int, int>& x, const pair<int, int>& y) -> bool {
- if (x.first / BLOCK != y.first / BLOCK)
- return x.first < y.first;
- return x.second < y.second;
- });
- build(1, 0, n - 1);
- build(a, 1, 0, n - 1);
- assert(check.count({ 0, n - 1 }));
- int ans = 0;
- int l = query[0].first, r = query[0].second;
- for (int i = l; i <= r; i++)
- add(a[i], +1);
- ans = max(ans, (get(0, get_max(l, r)) > 0) * (r - l + 1));
- for (int i = 1; i < (int)query.size(); i++) {
- if (ans >= (query[i].second - query[i].first + 1))
- continue;
- while (l < query[i].first)
- add(a[l++], -1);
- while (r < query[i].second)
- add(a[++r], +1);
- while (l > query[i].first)
- add(a[--l], +1);
- while (r > query[i].second)
- add(a[r--], -1);
- assert(l == query[i].first);
- assert(r == query[i].second);
- ans = max(ans, (get(0, get_max(l, r)) > 0) * (r - l + 1));
- }
- cout << ans << '\n';
- }
- signed main() {
- boost;
- int t = 1;
- cin >> t;
- while (t--)
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement