Submission #619781

#TimeUsernameProblemLanguageResultExecution timeMemory
619781colossal_pepeFinancial Report (JOI21_financial)C++17
100 / 100
382 ms29220 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <numeric>
using namespace std;

int n, d;
vector<int> a, p;

struct DSU {
    vector<int> e, mn;
    void init(int sz) {
        e.resize(sz, -1);
        mn.resize(sz);
        iota(mn.begin(), mn.end(), 0);
    }
    bool merge(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return 0;
        if (-e[x] < -e[y]) swap(x, y);
        e[x] += e[y], e[y] = x;
        mn[x] = mn[y] = min(mn[x], mn[y]);
        return 1;
    }
    int find(int x) {
        return (e[x] < 0 ? x : e[x] = find(e[x]));
    }
    int minReachable(int x) {
        return mn[find(x)];
    }
};

struct Bounds {
    vector<int> nxt;
    DSU dsu;
    void init(vector<int> v) {
        int sz = v.size();
        nxt.resize(sz);
        dsu.init(sz);
        set<pair<int, int>> s;
        nxt[0] = 0;
        s.insert({v[0], 0});
        for (int i = 1; i < sz; i++) {
            if (s.size() > d) s.erase({v[i - d - 1], i - d - 1});
            nxt[i] = (*s.begin()).second;
            s.insert({v[i], i});
        }
    }
    void setBound(int i) {
        dsu.merge(i, nxt[i]);
    }
    int getBound(int i) {
        return dsu.minReachable(i);
    }
};

struct SGT {
    vector<int> v;
    SGT(int sz) {
        v.resize(4 * sz, 0);
    }
    void update(int u, int l, int r, int i, int x) {
        if (l == r) v[u] = x;
        else {
            int mid = (l + r) / 2;
            if (i <= mid) update(2 * u, l, mid, i, x);
            else update(2 * u + 1, mid + 1, r, i, x);
            v[u] = max(v[2 * u], v[2 * u + 1]);
        }
    }
    int query(int u, int l, int r, int L, int R) {
        if (R < l or r < L) return 0;
        else if (L <= l and r <= R) return v[u];
        else {
            int mid = (l + r) / 2;
            return max(query(2 * u, l, mid, L, R), query(2 * u + 1, mid + 1, r, L, R));
        }
    }
};

int solve() {
    sort(p.begin(), p.end(), [](int i, int j) {
        if (a[i] == a[j]) return i > j;
        return a[i] < a[j];
    });
    SGT sgt(n);
    Bounds bounds;
    bounds.init(a);
    int ans = 0;
    for (int i : p) {
        bounds.setBound(i);
        int l = bounds.getBound(i);
        int x = sgt.query(1, 0, n - 1, l, i) + 1;
        ans = max(ans, x);
        sgt.update(1, 0, n - 1, i, x);
    }
    return ans;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> d;
    a.resize(n), p.resize(n);
    iota(p.begin(), p.end(), 0);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    cout << solve() << endl;
    return 0;
}

Compilation message (stderr)

Main.cpp: In member function 'void Bounds::init(std::vector<int>)':
Main.cpp:45:26: warning: comparison of integer expressions of different signedness: 'std::set<std::pair<int, int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   45 |             if (s.size() > d) s.erase({v[i - d - 1], i - d - 1});
      |                 ~~~~~~~~~^~~
#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...