Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef vector<int> vi;
- typedef pair<int, int> pii;
- #define ff first
- #define ss second
- #define y1 y111
- #define X first
- #define Y second
- #define mk make_pair
- #define inb push_back
- #define all(v) v.begin(), v.end()
- const int MAXN = (int)1e6 + 9, MAXN1 = (int)2e4 + 7;
- const int INFint = (int)1e9 + 7, P = 31;
- const ll INFll = (ll)1e18 + 7, MOD = (ll)1e9 + 7;
- const double INFfl = 1e18 * 4 + 7;
- const double EPS = 1e-7;
- const double PI = atan2(0, -1);
- int solve();
- int main()
- {
- #define TASK ""
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
- #else
- //freopen(TASK".in", "r", stdin), freopen(TASK".out", "w", stdout);
- #endif
- solve();
- }
- const int STRBUF = (int)1e6 + 7;
- char buf[STRBUF];
- string get_str()
- {
- scanf(" %s", buf);
- return string(buf);
- }
- const ll MINF = -1e18;
- struct SegmentTree
- {
- struct Node
- {
- ll val, add;
- Node() { val = 0, add = 0; };
- Node(ll x) { val = x, add = 0; };
- };
- vector<Node> t;
- SegmentTree() {};
- SegmentTree(vector<ll> &a)
- {
- t.resize(4 * (int)a.size());
- build(0, 0, (int)a.size() - 1, a);
- }
- Node max(Node a, Node b)
- {
- if (a.val > b.val)
- return a;
- return b;
- }
- void build(int v, int tl, int tr, vector<ll>& a)
- {
- if (tl == tr)
- {
- t[v] = Node(a[tl]);
- return;
- }
- int tm = tl + tr >> 1;
- build(2 * v + 1, tl, tm, a);
- build(2 * v + 2, tm + 1, tr, a);
- t[v] = max(t[2 * v + 1], t[2 * v + 2]);
- }
- void push(int v, int tl, int tr)
- {
- if (!t[v].add)
- return;
- t[v].val += t[v].add;
- if (tl != tr)
- {
- t[2 * v + 1].add += t[v].add;
- t[2 * v + 2].add += t[v].add;
- }
- t[v].add = 0;
- }
- void update(int v, int tl, int tr, int l, int r, ll val)
- {
- push(v, tl, tr);
- if (tl > r || tr < l)
- return;
- if (l <= tl && tr <= r)
- {
- t[v].add += val;
- push(v, tl, tr);
- return;
- }
- int tm = tl + tr >> 1;
- update(2 * v + 1, tl, tm, l, r, val);
- update(2 * v + 2, tm + 1, tr, l, r, val);
- t[v] = max(t[2 * v + 1], t[2 * v + 2]);
- }
- ll get(int v, int tl, int tr, int l, int r)
- {
- push(v, tl, tr);
- if (tl > r || tr < l)
- return MINF;
- if (l <= tl && tr <= r)
- {
- return t[v].val;
- }
- int tm = tl + tr >> 1;
- ll ql = get(2 * v + 1, tl, tm, l, r);
- ll qr = get(2 * v + 2, tm + 1, tr, l, r);
- if (ql < qr)
- swap(ql, qr);
- return ql;
- }
- };
- int solve()
- {
- int n, k;
- ll w, v;
- scanf("%d %d %lld %lld", &n, &k, &w, &v);
- vector<ll> d(n);
- for (int i = 0; i < n; ++i)
- scanf("%lld", &d[i]);
- SegmentTree T = SegmentTree(d);
- vi nxt(n, -1);
- for (int i = n - 2; i >= 0; --i)
- {
- T.update(0, 0, n - 1, i + 1, n - 1, -v);
- int l = i, r = min(i + k + 1, n + 1);
- int rbound = r - 1;
- while (r - l > 1)
- {
- int mid = l + r >> 1;
- if (T.get(0, 0, n - 1, mid, rbound) >= w)
- l = mid;
- else
- r = mid;
- }
- if (T.get(0, 0, n - 1, l, rbound) >= w)
- {
- nxt[i] = l;
- }
- if (d[i + 1] >= w)
- nxt[i] = max(nxt[i], i + 1);
- }
- int INF = 200000;
- vi dp(n, INF);
- dp[0] = 0;
- for (int i = 0; i < n; ++i)
- {
- if (nxt[i] == -1)
- continue;
- dp[nxt[i]] = min(dp[i] + 1, dp[nxt[i]]);
- }
- printf("%d\n", (dp[n - 1] == INF) ? (-1) : (dp[n - 1]));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement