Submission #679783

#TimeUsernameProblemLanguageResultExecution timeMemory
679783bashkortFinancial Report (JOI21_financial)C++17
100 / 100
335 ms12920 KiB
//#define _GLIBCXX_DEBUG

//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

using namespace std;


#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

template<typename T>
using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());

#define ll long long
#define trace(x) cout << #x << " = " << (x) << endl;
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define uniq(x) x.resize(unique(all(x)) -  begin(x))
#define ld long double
#define sz(s) (int) size(s)
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
#define mt make_tuple
#define int128 __int128

template<typename T>
bool ckmn(T &x, T y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}

template<typename T>
bool ckmx(T &x, T y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}

int bit(int x, int b) {
    return (x >> b) & 1;
}


int rand(int l, int r) { return (int) ((ll) rnd() % (r - l + 1)) + l; }

const ll infL = 3e18;
const int infI = 1e9 + 7;
const int N = 300000;
const ll mod = 998244353;
const ld eps = 1e-9;

vector<int> t;
int sz = 1;

void init(int n) {
    while (sz < n) sz <<= 1;
    t.resize(sz << 1);
    fill(all(t), -infI);
}

void Set(int i, int v) {
    int x = i + sz;
    while (x) {
        ckmx(t[x], v);
        x >>= 1;
    }
}

int get(int l, int r, int x = 1, int lx = 0, int rx = sz) {
    if (l >= rx || lx >= r) return -infI;
    if (l <= lx && rx <= r) return t[x];
    int m = (lx + rx) >> 1;
    return max(get(l, r, x << 1, lx, m), get(l, r, x << 1 | 1, m, rx));
}


int n, d;

set <pair<int, int>> st; //l, r
int get(int x) {
    auto it = st.upper_bound(mp(x, infI));
    if (it == st.begin()) return 0;
    it = prev(it);
    auto[L, R] = *it;
    if (R < x) {
        return R - d + 1;
    }
    if (x - L >= d) return x - d;
    else {
        if (it == st.begin()) return 0;
        else {
            it = prev(it);
            auto [l, r] = *it;
            int y = r - d + 1;
            assert(l <= y && y <= r);
            assert(0 <= y);
            return y;
        }
    }
}

void del(int x) {
    auto it = st.upper_bound(mp(x, infI));
    if (it == st.begin()) return;
    assert(it != st.begin());
    it = prev(it);
    auto[L, R] = *it;
    if (R < x) return;
    st.erase(it);
    int RR = x - 1, LL = x + 1;
    if (RR - L + 1 >= d) st.insert(mp(L, RR));
    if (R - LL + 1 >= d) st.insert(mp(LL, R));
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> d;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) cin >> a[i];
    vector<int> yy = a;
    sort(all(yy));
    uniq(yy);
    for (int i = 0; i < n; ++i) a[i] = lower_bound(all(yy), a[i]) - begin(yy);
    vector<int> ord(n);
    iota(all(ord), 0);
    sort(all(ord), [&a](int i, int j) { return a[i] < a[j]; });
    if (d == 1) {
        vector<int> ans(n);
        vector<int> st;
        for (int i = n - 1; i > -1; --i) {
            while (!st.empty() && a[st.back()] <= a[i]) st.pop_back();
            if (st.empty()) ans[i] = 1;
            else ans[i] = ans[st.back()] + 1;
            st.push_back(i);
        }
        cout << *max_element(all(ans));
    } else if (d == n) {
        init(n);
        for (int i = 0; i < n; ++i) {
            int mx = max(0, get(0, a[i])) + 1;
            Set(a[i], mx);
        }
        cout << t[1];
        return 0;
    } else {
        init(n);
        st.insert(mp(0, n - 1));
        //r, l
        for (int idx = 0; idx < n;) {
            vector<int> now;
            int J = idx;
            while (J < n && a[ord[J]] == a[ord[idx]]) {
//                trace(a[ord[J]])

                now.push_back(ord[J]);
                ++J;
            }
            idx = J;
            vector<int> ans;
            for (int i : now) {
                int l = get(i);
                ans.push_back(max(0, get(l, i)) + 1);
            }
            for (int j = 0; j < sz(now); ++j) {
                int i = now[j];
                Set(i, ans[j]);
                del(i);
            }
        }
        cout << t[1];
    }
    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...