Submission #1350838

#TimeUsernameProblemLanguageResultExecution timeMemory
1350838msab3fFinancial Report (JOI21_financial)C++20
100 / 100
258 ms29160 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 300'000 + 10;
const int MAX_LG = 19;

int n, d, arr[MAX_N], mn[MAX_N][MAX_LG];

namespace Seg {
    int tree[4 * MAX_N];
    bool lazy[4 * MAX_N];

#define mid (l + r) >> 1
#define lc id << 1
#define rc (lc | 1)

    inline void update(int id) {
        tree[id] = max(tree[lc], tree[rc]);
    }

    void build(int id = 1, int l = 0, int r = MAX_N) {
        if (r - l == 1) {
            tree[id] = l == 0 ? 1 : 0;
        } else {
            build(lc, l, mid);
            build(rc, mid, r);
            update(id);
        }
    }

    inline void apply(int id) {
        tree[id] = 0;
        lazy[id] = true;
    }

    inline void push_down(int id) {
        if (!lazy[id]) return;
        apply(lc);
        apply(rc);
        lazy[id] = false;
    }

    void erase(int ql, int qr, int id = 1, int l = 0, int r = MAX_N) {
        if (ql <= l && r <= qr) {
            apply(id);
        } else {
            push_down(id);
            if (ql < mid) {
                erase(ql, qr, lc, l, mid);
            }
            if (mid < qr) {
                erase(ql, qr, rc, mid, r);
            }
            update(id);
        }
    }

    void modify(int i, int x, int id = 1, int l = 0, int r = MAX_N) {
        if (r - l == 1) {
            tree[id] = max(tree[id], x);
        } else {
            push_down(id);
            if (i < mid) {
                modify(i, x, lc, l, mid);
            } else {
                modify(i, x, rc, mid, r);
            }
            update(id);
        }
    }

    int get(int ql, int qr, int id = 1, int l = 0, int r = MAX_N) {
        if (ql <= l && r <= qr) {
            return tree[id];
        }
        push_down(id);
        int res = 0;
        if (ql < mid) {
            res = max(res, get(ql, qr, lc, l, mid));
        }
        if (mid < qr) {
            res = max(res, get(ql, qr, rc, mid, r));
        }
        return res;
    }
};

int get_mn(int l, int r) {
    int k = __lg(r - l + 1);
    return min(mn[r][k], mn[l + (1 << k) - 1][k]);
}

void compress() {
    vector<int> help;
    for (int i = 1; i <= n; ++i) {
        help.push_back(arr[i]);
    }
    sort(help.begin(), help.end());
    help.erase(unique(help.begin(), help.end()), help.end());
    for (int i = 1; i <= n; ++i) {
        arr[i] = int(lower_bound(help.begin(), help.end(), arr[i]) - help.begin()) + 1;
    }
}

int main() {
    cin >> n >> d;

    for (int i = 1; i <= n; ++i) {
        cin >> arr[i];
    }

    compress();

    for (int i = 1; i <= n; ++i) {
        mn[i][0] = arr[i];
        for (int j = 1; (1 << j) <= i; ++j) {
            mn[i][j] = min(mn[i][j - 1], mn[i - (1 << (j - 1))][j - 1]);
        }
    }

    Seg::build();

    for (int i = 1; i <= n; ++i) {
        if (i > d + 1) {
            Seg::erase(1, get_mn(i - d, i - 1));
        }
        if (i < n) {
            Seg::modify(arr[i], Seg::get(0, arr[i]) + 1);
        } else {
            cout << max(Seg::get(0, arr[i]), Seg::get(arr[i], MAX_N) - 1) << '\n';
        }
    }
}
#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...