제출 #1267861

#제출 시각아이디문제언어결과실행 시간메모리
1267861minhmc2019Rabbit Carrot (LMIO19_triusis)C++20
100 / 100
227 ms23348 KiB
#include <bits/stdc++.h>
#define FOR(i, l, r, x) for(int i = l; i <= r; i += x)
#define FOD(i, l, r, x) for(int i = l; i >= r; i -= x)
#define debug(x) cout << "[DEBUG]:  " << #x << " = " << x << endl;
#define BIT(x) (1 << (x))
#define int long long
using namespace std;

const int N = 4e5 + 5;
const int mod = 1e9 + 7;
const int inf = 1e18;

struct SegmentTree {
    int st[4 * N];

    void upd(int id, int l, int r, int pos, int val) {
        if (!(l <= pos && pos <= r)) return;
        if (l == r) {
            st[id] = val;
            return;
        }

        int mid = (l + r) >> 1;
        upd(id << 1, l, mid, pos, val);
        upd(id << 1 | 1, mid + 1, r, pos, val);

        st[id] = max(st[id << 1], st[id << 1 | 1]);
    }

    int get(int id, int l, int r, int u, int v) {
        if (r < u || v < l) return -inf;
        if (u <= l && r <= v) return st[id];

        int mid = (l + r) >> 1;

        return max(get(id << 1, l, mid, u, v),
                   get(id << 1 | 1, mid + 1, r, u, v));
    }
};

int n, M, h[N];

inline bool isOn(int mask, int i) {
    return ((mask >> i) & 1LL);
}

namespace sub1 {
    void solve() {
        int ans = 0;

        FOR(mask, 0, BIT(n) - 1, 1) {
            int last_i = -1;
            bool isValid = true;

            FOR(i, 0, n - 1, 1) {
                if (!isOn(mask, i)) continue;

                bool can_move = (h[last_i + 1] + ((i - last_i) * M) >= h[i + 1]);

                if (!can_move) {
                    isValid = false;
                    break;
                }

                last_i = i;
            }

            if (isValid) {
                ans = max(ans, (int)__builtin_popcountll(mask));
            }
        }

        cout << n - ans << endl;
    }
}

namespace sub2 {
    int dp[N] = {};

    inline bool isGreater(const int &i, const int &j) {
        return ((h[j] + (i - j) * M) >= h[i]);
    }

    void solve() {
        dp[0] = 1;

        int ans = 1;

        FOR(i, 0, n, 1) {
            FOR(j, 0, i - 1, 1) {
                if (isGreater(i, j)) {
                    if (dp[j] >= 1) dp[i] = max(dp[i], dp[j] + 1);
                }
            }
            ans = max(ans, dp[i]);
        }
//
//        FOR(i, 0, n, 1) {
//            cout << dp[i] << " ";
//        }
//        cout << '\n';

        cout << n - ans + 1 << endl;
    }
}

namespace sub4 {
    SegmentTree st;
    int a[N], dp[N];
    vector <int> vec;
    map <int, int> mp;

    const int lim = 2e5 + 5;

    void Compress() {
        sort(begin(vec), end(vec));
        vec.resize(unique(begin(vec), end(vec)) - begin(vec));

        int id = 0;

        for(const int &num : vec) {
//            cout << num << '\n';
            mp[num] = ++id;
        }

        FOR(i, 0, n, 1) {
            a[i] = mp[a[i]];
        }
    }

    void solve() {
        vec.reserve(n + 5);
        FOR(i, 0, n, 1) {
            a[i] = h[i] - i * M;
            vec.push_back(a[i]);
        }

//        FOR(i, 0, n, 1) {
//            cout << a[i] << " ";
//        }
//        cout << '\n';

        Compress();

        dp[0] = 1;

        int ans = 0;
//
////
//        FOR(i, 0, n, 1) {
//            cout << a[i] << " ";
//        }
//        cout << '\n';
//        cout << '\n';

        FOR(i, 0, n, 1) {
            int val = a[i];

            int dpj = st.get(1, 0, lim, val, lim);

            if (dpj != 0) {
                dp[i] = max(dp[i], dpj + 1);
            }

            st.upd(1, 0, lim, val, dp[i]);
            ans = max(ans, dp[i]);
        }

//        FOR(i, 0, n, 1) {
//            cout << dp[i] << " ";
//        }
//        cout << '\n';

        cout << n - (ans - 1) << '\n';
    }
}

void solve() {
    cin >> n >> M;
    FOR(i, 1, n, 1) cin >> h[i];
    h[0] = 0;

    if (n <= 20) {
        sub1::solve();
    } else if (n <= 5000) {
        sub2::solve();
    } else {
        sub4::solve();
    }
}

signed main() {
//    freopen("random.inp", "r", stdin);
//    freopen("sol2.out", "w", stdout);

    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...