Submission #958025

#TimeUsernameProblemLanguageResultExecution timeMemory
958025Soumya1Long Distance Coach (JOI17_coach)C++17
100 / 100
128 ms27184 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll inf = 1e18;
struct Line {
  mutable ll k, m, p;
  bool operator<(const Line& o) const { return k < o.k; }
  bool operator<(ll x) const { return p < x; }
};

struct LineContainer : multiset<Line, less<>> {
  // (for doubles, use inf = 1/.0, div(a,b) = a/b)
  static const ll inf = LLONG_MAX;
  ll div(ll a, ll b) { // floored division
    return a / b - ((a ^ b) < 0 && a % b); }
  bool isect(iterator x, iterator y) {
    if (y == end()) return x->p = inf, 0;
    if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
    else x->p = div(y->m - x->m, x->k - y->k);
    return x->p >= y->p;
  }
  void add(ll k, ll m) {
    auto z = insert({k, m, 0}), y = z++, x = y;
    while (isect(y, z)) z = erase(z);
    if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
    while ((y = x) != begin() && (--x)->p >= y->p)
      isect(x, erase(y));
  }
  ll query(ll x) {
    assert(!empty());
    auto l = *lower_bound(x);
    return l.k * x + l.m;
  }
};
void testCase() {
  ll n, x, m, w, t;
  cin >> x >> n >> m >> w >> t;
  vector<ll> s(n + 2);
  for (int i = 1; i <= n; i++) cin >> s[i];
  s[n + 1] = x;
  vector<ll> c(m + 1), d(m + 1);
  for (int i = 1; i <= m; i++) cin >> d[i] >> c[i];
  vector<int> ord(m + 1);
  iota(ord.begin(), ord.end(), 0);
  sort(ord.begin(), ord.end(), [&](int i, int j) { return d[i] < d[j]; });
  {
    auto cc = c, dd = d;
    for (int i = 0; i <= m; i++) {
      cc[i] = c[ord[i]];
      dd[i] = d[ord[i]];
    }
    c = cc, d = dd;
  }
  vector<ll> mn(m + 1, inf);
  for (int i = 1; i <= n + 1; i++) {
    ll x = s[i] % t;
    if (!x) continue;
    int j = lower_bound(d.begin(), d.end(), x) - d.begin() - 1;
    mn[j] = min(mn[j], s[i] / t);
  }
  LineContainer lc;
  vector<ll> sum(m + 1);
  for (int i = 1; i <= m; i++) sum[i] = sum[i - 1] + c[i];
  vector<ll> dp(m + 1, inf);
  dp[0] = (x / t + 1) * w;
  lc.add(0, -dp[0]);
  for (int i = 1; i <= m; i++) {
    dp[i] = dp[i - 1] + ((x - d[i]) / t + 1) * w;
    if (mn[i] != inf) dp[i] = min(dp[i], -lc.query(mn[i] * w) + i * mn[i] * w + sum[i]);
    lc.add(i, -(dp[i] - sum[i]));
  }
  cout << dp[m] << "\n";
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  testCase();
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...