結果

問題 No.3509 Get More Money
コンテスト
ユーザー テナガザル
提出日時 2026-04-19 16:22:49
言語 C++23
(gcc 15.2.0 + boost 1.89.0)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 649 ms / 2,000 ms
コード長 5,092 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,808 ms
コンパイル使用メモリ 204,316 KB
実行使用メモリ 28,928 KB
最終ジャッジ日時 2026-04-19 16:23:37
合計ジャッジ時間 38,538 ms
ジャッジサーバーID
(参考情報)
judge1_1 / judge2_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 60
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <stack>

template <typename T, typename X> class LazySegTree
{
private:
  const T et;
  const X ex;
  int num;
  std::vector<T> dat;
  std::vector<X> lazy;
  T (*const eval)(const T, const T) {};
  T (*const fa)(const T, const X) {};
  X (*const fm)(const X, const X) {};
  X (*const fp)(const X, int) {};
    
public:
  LazySegTree(std::vector<T> &v, T Et, X Ex, T (*valcal)(T, T), T (*lazyupdate)(T, X), X (*lazypropagation)(X, X), X (*rangelazy)(X, int)) : et(Et), ex(Ex), eval(valcal), fa(lazyupdate), fm(lazypropagation), fp(rangelazy)
  {
    int siz = static_cast<int>(v.size());
    for (num = 1; num < siz; num <<= 1);
    dat = std::vector<T> (2 * num - 1, et);
    lazy = std::vector<X> (2 * num - 1, ex);
    for (int i = 0; i < siz; ++i) dat[i + num - 1] = v[i];
    for (int i = num - 2; i >= 0; --i) dat[i] = eval(dat[i * 2 + 1], dat[i * 2 + 2]);
  }

  LazySegTree(int n, T Et, X Ex, T (*valcal)(T, T), T (*lazyupdate)(T, X), X (*lazypropagation)(X, X), X (*rangelazy)(X, int)) : et(Et), ex(Ex), eval(valcal), fa(lazyupdate), fm(lazypropagation), fp(rangelazy)
  {
    for (num = 1; num < n; num <<= 1);
    dat = std::vector<T> (2 * num - 1, et);
    lazy = std::vector<X> (2 * num - 1, ex);
  }

  //update [left,right)
  void update(int left, int right, X val)
  {
    std::stack<std::pair<int, int>> st;
    std::stack<int> s;
    for (st.push({0, num}); !st.empty();)
    {
      auto v = st.top();
      st.pop();
      int now = (num + v.first) / (v.second - v.first) - 1;
      lazyupdate(now, v.second - v.first);
      if (left <= v.first && v.second <= right)
      {
        lazy[now] = fm(lazy[now], val);
        lazyupdate(now, v.second - v.first);
      }
      else if (!(v.second <= left || right <= v.first))
      {
        st.push({(v.first + v.second) / 2, v.second});
        st.push({v.first, (v.first + v.second) / 2});
        s.push(now);
      }
    }
    while (!s.empty())
    {
      int index = s.top();
      dat[index] = eval(dat[2 * index + 1], dat[2 * index + 2]);
      s.pop();
    }
  }

  //get value [left,right)
  T getval(int left, int right)
  {
    std::stack<std::pair<int, int>> s;
    T ans = et;
    for (s.push({0, num}); !s.empty();)
    {
      auto v = s.top();
      s.pop();
      int now = (num + v.first) / (v.second - v.first) - 1;
      lazyupdate(now, v.second - v.first);
      if (left <= v.first && v.second <= right) ans = eval(ans, dat[now]);
      else if (!(v.second <= left || right <= v.first))
      {
        s.push({(v.first + v.second) / 2, v.second});
        s.push({v.first, (v.first + v.second) / 2});
      }
    }
    return ans;
  }

  //get value [id]
  T getval(int id) {return getval(id, id + 1);}

private:
  void lazyupdate(int index, int len)
  {
    if (lazy[index] == ex) return;
    if (index < num - 1)
    {
      lazy[index * 2 + 1] = fm(lazy[index * 2 + 1], lazy[index]);
      lazy[index * 2 + 2] = fm(lazy[index * 2 + 2], lazy[index]);
    }
    dat[index] = fa(dat[index], fp(lazy[index], len));
    lazy[index] = ex;
  }
};

/*
区間代入区間和
auto eval = [](long long a, long long b) -> long long {return a + b;};
auto fa = [](long long a, long long b) -> long long {return b;};
auto fp = [](long long a, int len) -> long long {return a * len;};
LazySegTree<long long, long long> lsg(v, 0, 使わない値, eval, fa, fa, fp);

*/ 

using namespace std;

void solve()
{
  int n;
  long long k;
  cin >> n >> k;
  vector<int> a(n), b(n), c(n), d(n);
  for (int i = 0; i < n; ++i) cin >> a[i];
  for (int i = 0; i < n; ++i) cin >> b[i];
  for (int i = 0; i < n; ++i) cin >> c[i];
  for (int i = 0; i < n; ++i) cin >> d[i];
  auto eval = [](long long a, long long b) -> long long {return max(a, b);};
  auto fa = [](long long a, long long b) -> long long {return a + b;};
  auto fp = [](long long a, int len) -> long long {return a;};
  vector<long long> inif(n, 0);
  LazySegTree<long long, long long> lsg(inif, 0, 0, eval, fa, fa, fp);
  multiset<pair<int, pair<int, int>>> st;
  long long ans = 0;
  for (int i = 0; i < n; ++i)
  {
    int f = 0;
    st.insert({a[i], {-i, b[i]}});
    while (d[i] > 0 && !st.empty())
    {
      auto itr = st.begin();
      auto [v, cid] = *itr;
      if (v >= c[i]) break;
      auto [id, cap] = cid;
      id = -id;
      st.erase(itr);
      if (id == i)
      {
        long long fma = min(cap, d[i]);
        ans += fma * (c[i] - v);
        cap -= fma;
        d[i] -= fma;
        f += fma;
        if (cap > 0) st.insert({v, {-id, cap}});
      }
      else if (id < i)
      {
        long long lrma = lsg.getval(id, i);
        if (lrma >= k) continue;
        long long nok = min(d[i], cap);
        nok = min(nok, k - lrma);
        lsg.update(id, i, nok);
        ans += nok * (c[i] - v);
        d[i] -= nok;
        cap -= nok;
        f += nok;
        if (cap > 0) st.insert({v, {-id, cap}});
      }
    }
    if (f > 0) st.insert({c[i], {-i, f}});
  }
  cout << ans << endl;
}

int main()
{
  int t;
  cin >> t;
  while (t--) solve();
}
0