제출 #960385

#제출 시각아이디문제언어결과실행 시간메모리
960385tvladm2009서열 (APIO23_sequence)C++17
100 / 100
1331 ms66212 KiB
#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>
#include <random>

using namespace std;
template<typename T1, typename T2> inline void chkmin(T1 &a, T2 b) {if (a > b) a = b;}
template<typename T1, typename T2> inline void chkmax(T1 &a, T2 b) {if (a < b) a = b;}
#define files(FILENAME) read(FILENAME); write(FILENAME)
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define all(c) (c).begin(), (c).end()
#define sz(c) (int)(c).size()
#define left left228
#define right right228
#define y1 y1228
#define mp make_pair
#define pb push_back
#define y2 y2228
#define rank rank228
using ll = long long;
using ld = long double; 
const string FILENAME = "input";
const int MAXN = 500228;

vector<int> pos[MAXN];
pair<int, int> tree[4 * MAXN + 228];
int lazy[4 * MAXN + 228];

pair<int, int> join(pair<int, int> a, pair<int, int> b) {
    return mp(min(a.first, b.first), max(a.second, b.second));
}

void push(int v) {
    tree[2 * v].first += lazy[v];
    tree[2 * v + 1].first += lazy[v];
    tree[2 * v].second += lazy[v];
    tree[2 * v + 1].second += lazy[v];
    lazy[2 * v] += lazy[v];
    lazy[2 * v + 1] += lazy[v];
    lazy[v] = 0;
}

void add(int l, int r, int x, int v = 1, int tl = 0, int tr = MAXN) {
    if (l <= tl && tr <= r) {
        tree[v].first += x;
        tree[v].second += x;
        lazy[v] += x;
        return;
    }
    if (l >= tr || r <= tl) {
        return;
    }
    push(v);
    int tm = (tl + tr) / 2;
    add(l, r, x, 2 * v, tl, tm);
    add(l, r, x, 2 * v + 1, tm, tr);
    tree[v] = join(tree[2 * v], tree[2 * v + 1]);
}

pair<int, int> get(int l, int r, int v = 1, int tl = 0, int tr = MAXN) {
    if (l <= tl && tr <= r) {
        return tree[v];
    }
    if (l >= tr || r <= tl) {
        return mp(MAXN, -MAXN);
    }
    push(v);
    int tm = (tl + tr) / 2;
    auto p1 = get(l, r, 2 * v, tl, tm), p2 = get(l, r, 2 * v + 1, tm, tr);
    tree[v] = join(tree[2 * v], tree[2 * v + 1]);
    return join(p1, p2);
}

int sequence(int n, vector<int> a) {
    for (int i = 0; i < n; i++) {
        a[i]--;
        pos[a[i]].pb(i);
    }
    for (int i = 0; i < n; i++) {
        add(i + 1, n + 1, 1);
    }
    int ret = 1;
    vector<int> pref_min1(n), pref_min2(n), pref_max1(n), pref_max2(n), suff_min1(n), suff_min2(n), suff_max1(n), suff_max2(n);
    for (int val = 0; val < n; val++) {
        for (int i = 0; i < sz(pos[val]); i++) {
            pair<int, int> res = get(0, pos[val][i] + 1);
            pref_min1[i] = res.first;
            pref_max1[i] = res.second;
            res = get(pos[val][i] + 1, n + 1);
            suff_min1[i] = res.first;
            suff_max1[i] = res.second;
        }
        for (auto p: pos[val]) {
            add(p + 1, n + 1, -2);
        }
        for (int i = 0; i < sz(pos[val]); i++) {
            pair<int, int> res = get(0, pos[val][i] + 1);
            pref_min2[i] = res.first;
            pref_max2[i] = res.second;
            res = get(pos[val][i] + 1, n + 1);
            suff_min2[i] = res.first;
            suff_max2[i] = res.second;
        }
        int l = 1, r = sz(pos[val]) + 1, sol = 0;
        while (l < r - 1) {
            int m = (l + r) / 2;
            bool ok = false;
            for (int i = 0; i + m <= sz(pos[val]); i++) {
                if (pref_min1[i] <= suff_max1[i + m - 1] && suff_min1[i + m - 1] <= pref_max1[i]) {
                    ok = true;
                } else if (pref_min2[i] <= suff_max2[i + m - 1] && suff_min2[i + m - 1] <= pref_max2[i]) {
                    ok = true;
                } else if (pref_max1[i] <= suff_min1[i + m - 1] && suff_max2[i + m - 1] <= pref_min2[i]) {
                    ok = true;
                } else if (suff_max1[i] <= pref_min1[i + m - 1] && pref_max2[i + m - 1] <= suff_min2[i]) {
                    ok = true;
                }
            }
            if (ok == true) {
                l = m;
                sol = m;
            } else {
                r = m;
            }
        }
        chkmax(ret, sol);
    }
    return ret;
}

/**
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //read(FILENAME);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    cout << sequence(n, a) << '\n';
    return 0;
}
**/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...