Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC target("avx2")
- #pragma GCC optimization("O3")
- #pragma GCC optimization("unroll-loops")
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <queue>
- #include <cmath>
- #define task "SALES"
- using namespace std;
- using ll = long long;
- using ld = long double;
- const int N = 5e5 + 2;
- int n;
- ll u, d, s, sum[N];
- ll dp[N], f[N];
- int maxn(0);
- const ll Inf = 1e16;
- struct fes
- {
- ll t, m, l;
- bool operator<(const fes &a) const
- {
- return t < a.t || (t == a.t && l < a.l);
- }
- } a[N];
- #define BIT(i, x) (((x) >> (i)) & 1)
- struct Trie
- {
- Trie *child[2];
- ll v;
- Trie()
- {
- child[0] = child[1] = NULL;
- v = -Inf;
- }
- } lower, upper;
- void Add(Trie *a, int x, ll v)
- {
- int id = maxn;
- while (1)
- {
- if (id == -1)
- {
- a->v = max(a->v, v);
- return;
- }
- if (!(a->child[BIT(id, x)]))
- a->child[BIT(id, x)] = new Trie;
- a->v = max(a->v, v);
- a = a->child[BIT(id, x)];
- --id;
- }
- }
- ll getup(Trie *a, int x)
- {
- int id = maxn;
- ll ans = -Inf;
- while (1)
- {
- if (id == -1)
- {
- ans = max(ans, a->v);
- break;
- }
- if (BIT(id, x))
- {
- if (a->child[1])
- a = a->child[1];
- else
- break;
- }
- else
- {
- if (a->child[1])
- ans = max(ans, a->child[1]->v);
- if (a->child[0])
- a = a->child[0];
- else
- break;
- }
- --id;
- }
- return ans;
- }
- ll getlow(Trie *a, int x)
- {
- int id = maxn;
- ll ans = -Inf;
- while (1)
- {
- if (id == -1)
- {
- ans = max(ans, a->v);
- break;
- }
- if (BIT(id, x))
- {
- if (a->child[0])
- ans = max(ans, a->child[0]->v);
- if (a->child[1])
- a = a->child[1];
- else
- break;
- }
- else
- {
- if (a->child[0])
- a = a->child[0];
- else
- break;
- }
- --id;
- }
- return ans;
- }
- void Read()
- {
- cin >> n >> u >> d >> s;
- for (int i = 1; i <= n; ++i)
- cin >> a[i].t >> a[i].l >> a[i].m;
- sort(a + 1, a + n + 1);
- maxn = max(maxn, (int)log2(s));
- for (int i = 1; i <= n; ++i)
- sum[i] = sum[i - 1] + a[i].m,
- maxn = max(maxn, (int)log2(a[i].l));
- }
- void Solve()
- {
- fill_n(dp, N, -Inf);
- /// BASE CASE
- Add(&lower, s, s * d);
- Add(&upper, s, -u * s);
- /// END BASE CASE
- int j;
- for (int i = 1; i <= n; ++i)
- {
- j = i;
- while (j <= n && a[i].t == a[j].t)
- ++j;
- ll ilr(-Inf), irl(-Inf), pilr(-Inf), pirl(-Inf);
- for (int t = i; t < j; ++t)
- {
- /// Calculate f[]
- f[t] = max(getlow(&lower, a[t].l) - d * a[t].l,
- getup(&upper, a[t].l) + u * a[t].l);
- /// Calculate dp[]
- pilr = max(pilr, -(u + d) * a[t].l - sum[t - 1]);
- ilr = max(ilr, u * a[t].l + f[t] + pilr);
- dp[t] = d * a[t].l + ilr + sum[t];
- }
- for (int t = j - 1; t >= i; --t)
- {
- pirl = max(pirl, sum[t] + (u + d) * a[t].l);
- irl = max(irl, pirl + f[t] - d * a[t].l);
- dp[t] = max(dp[t], irl - u * a[t].l - sum[t - 1]);
- /// Update lower, upper
- Add(&lower, a[t].l, dp[t] + d * a[t].l);
- Add(&upper, a[t].l, dp[t] - u * a[t].l);
- }
- i = j - 1;
- }
- cout << max(getlow(&lower, s) - d * s, getup(&upper, s) + u * s);
- }
- int32_t main()
- {
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- if (fopen(task ".INP", "r"))
- freopen(task ".INP", "r", stdin),
- freopen(task ".OUT", "w", stdout);
- Read();
- Solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment