結果

問題 No.776 A Simple RMQ Problem
ユーザー mkawa2mkawa2
提出日時 2022-03-01 13:21:22
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 270 ms / 3,000 ms
コード長 7,187 bytes
コンパイル時間 2,226 ms
コンパイル使用メモリ 209,900 KB
実行使用メモリ 13,612 KB
最終ジャッジ日時 2024-07-07 19:12:21
合計ジャッジ時間 10,551 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 27 ms
5,632 KB
testcase_03 AC 99 ms
12,680 KB
testcase_04 AC 117 ms
6,944 KB
testcase_05 AC 196 ms
12,840 KB
testcase_06 AC 58 ms
7,892 KB
testcase_07 AC 125 ms
13,044 KB
testcase_08 AC 150 ms
8,048 KB
testcase_09 AC 59 ms
13,072 KB
testcase_10 AC 89 ms
8,192 KB
testcase_11 AC 161 ms
13,316 KB
testcase_12 AC 207 ms
13,504 KB
testcase_13 AC 209 ms
13,516 KB
testcase_14 AC 214 ms
13,432 KB
testcase_15 AC 205 ms
13,512 KB
testcase_16 AC 206 ms
13,544 KB
testcase_17 AC 270 ms
13,468 KB
testcase_18 AC 150 ms
13,564 KB
testcase_19 AC 232 ms
13,488 KB
testcase_20 AC 237 ms
13,612 KB
testcase_21 AC 237 ms
13,436 KB
testcase_22 AC 235 ms
13,520 KB
testcase_23 AC 239 ms
13,480 KB
testcase_24 AC 247 ms
13,476 KB
testcase_25 AC 56 ms
6,940 KB
testcase_26 AC 156 ms
13,500 KB
testcase_27 AC 136 ms
13,408 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// #include <atcoder/all>
// using namespace atcoder;
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(x) (x).begin(), (x).end()
#define popcnt(x) __builtin_popcount(x)
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vll = vector<ll>;
using vvi = vector<vector<int>>;
using vvll = vector<vector<ll>>;
const int lim = 1e9;
const ll inf = 1e18;
int dx[] = {1, 1, 0, -1, -1, -1, 0, 1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};

// const int mod = 1000000007;
const int mod = 998244353;
struct mint {
  ll x;  // typedef long long ll;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  mint operator-() const { return mint(-x); }
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod - a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1) a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint& operator/=(const mint a) { return *this *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream& operator>>(istream& is, mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }

int ceil_pow2(int n) {
  int x = 0;
  while ((1U << x) < (unsigned int)(n)) x++;
  return x;
}

template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S),
          F (*composition)(F, F), F (*id)()>
struct lazy_segtree {
 public:
  lazy_segtree() : lazy_segtree(0) {}
  explicit lazy_segtree(int n) : lazy_segtree(vector<S>(n, e())) {}
  explicit lazy_segtree(const vector<S>& v) : _n(int(v.size())) {
    log = ceil_pow2(_n);
    size = 1 << log;
    d = vector<S>(2 * size, e());
    lz = vector<F>(size, id());
    for (int i = 0; i < _n; i++) d[size + i] = v[i];
    for (int i = size - 1; i >= 1; i--) {
      update(i);
    }
  }

  void set(int p, S x) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--) push(p >> i);
    d[p] = x;
    for (int i = 1; i <= log; i++) update(p >> i);
  }

  S get(int p) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--) push(p >> i);
    return d[p];
  }

  S prod(int l, int r) {
    assert(0 <= l && l <= r && r <= _n);
    if (l == r) return e();

    l += size;
    r += size;

    for (int i = log; i >= 1; i--) {
      if (((l >> i) << i) != l) push(l >> i);
      if (((r >> i) << i) != r) push((r - 1) >> i);
    }

    S sml = e(), smr = e();
    while (l < r) {
      if (l & 1) sml = op(sml, d[l++]);
      if (r & 1) smr = op(d[--r], smr);
      l >>= 1;
      r >>= 1;
    }

    return op(sml, smr);
  }

  S all_prod() { return d[1]; }

  void apply(int p, F f) {
    assert(0 <= p && p < _n);
    p += size;
    for (int i = log; i >= 1; i--) push(p >> i);
    d[p] = mapping(f, d[p]);
    for (int i = 1; i <= log; i++) update(p >> i);
  }
  void apply(int l, int r, F f) {
    assert(0 <= l && l <= r && r <= _n);
    if (l == r) return;

    l += size;
    r += size;

    for (int i = log; i >= 1; i--) {
      if (((l >> i) << i) != l) push(l >> i);
      if (((r >> i) << i) != r) push((r - 1) >> i);
    }

    {
      int l2 = l, r2 = r;
      while (l < r) {
        if (l & 1) all_apply(l++, f);
        if (r & 1) all_apply(--r, f);
        l >>= 1;
        r >>= 1;
      }
      l = l2;
      r = r2;
    }

    for (int i = 1; i <= log; i++) {
      if (((l >> i) << i) != l) update(l >> i);
      if (((r >> i) << i) != r) update((r - 1) >> i);
    }
  }

  template <bool (*g)(S)>
  int max_right(int l) {
    return max_right(l, [](S x) { return g(x); });
  }
  template <class G>
  int max_right(int l, G g) {
    assert(0 <= l && l <= _n);
    assert(g(e()));
    if (l == _n) return _n;
    l += size;
    for (int i = log; i >= 1; i--) push(l >> i);
    S sm = e();
    do {
      while (l % 2 == 0) l >>= 1;
      if (!g(op(sm, d[l]))) {
        while (l < size) {
          push(l);
          l = (2 * l);
          if (g(op(sm, d[l]))) {
            sm = op(sm, d[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = op(sm, d[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }

  template <bool (*g)(S)>
  int min_left(int r) {
    return min_left(r, [](S x) { return g(x); });
  }
  template <class G>
  int min_left(int r, G g) {
    assert(0 <= r && r <= _n);
    assert(g(e()));
    if (r == 0) return 0;
    r += size;
    for (int i = log; i >= 1; i--) push((r - 1) >> i);
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2)) r >>= 1;
      if (!g(op(d[r], sm))) {
        while (r < size) {
          push(r);
          r = (2 * r + 1);
          if (g(op(d[r], sm))) {
            sm = op(d[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = op(d[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

 private:
  int _n, size, log;
  vector<S> d;
  vector<F> lz;

  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
  void all_apply(int k, F f) {
    d[k] = mapping(f, d[k]);
    if (k < size) lz[k] = composition(f, lz[k]);
  }
  void push(int k) {
    all_apply(2 * k, lz[k]);
    all_apply(2 * k + 1, lz[k]);
    lz[k] = id();
  }
};

struct S {
  ll mn;
  ll mx;
  ll val;
};
using F = long long;

S op(S l, S r) {
  ll mn = min(l.mn, r.mn);
  ll mx = max(l.mx, r.mx);
  ll v = max(max(l.val, r.val), r.mx - l.mn);
  return S{mn, mx, v};
}

S e() { return S{inf, -inf, -inf}; }

S mapping(F l, S r) { return S{r.mn + l, r.mx + l, r.val}; }

F composition(ll l, ll r) { return l + r; }

F id() { return 0LL; }

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, q;
  cin >> n >> q;
  vll a(n);
  rep(i, n) cin >> a[i];

  lazy_segtree<S, op, e, F, mapping, composition, id> st(n + 1);
  ll s = 0LL;
  st.set(0, S{s, s, -inf});
  rep(i, n) {
    s += a[i];
    st.set(i + 1, S{s, s, -inf});
  }

  rep(qi, q) {
    string t;
    cin >> t;
    if (t == "set") {
      int i;
      ll x;
      cin >> i >> x;
      i--;
      st.apply(i + 1, n + 1, x - a[i]);
      a[i] = x;
    } else {
      int l1, l2, r1, r2;
      cin >> l1 >> l2 >> r1 >> r2;
      l1--;
      r2++;
      ll s1 = inf, s2 = inf, t2 = -inf, t3 = -inf, ans = -inf;
      if (l1 < r1) s1 = st.prod(l1, min(l2, r1)).mn;
      if (l2 < r2) t3 = st.prod(max(l2, r1), r2).mx;
      int L = max(l1, r1), R = min(l2, r2);
      if (L < R) {
        auto ret = st.prod(L, R);
        s2 = ret.mn;
        t2 = ret.mx;
        ans = max(ans, ret.val);
      }
      // cout<<s1<<" "<<s2<<" "<<t2<<" "<<t3<<" "<<ans<<endl;
      ans = max(ans, max(t2, t3) - s1);
      ans = max(ans, t3 - min(s1, s2));
      cout << ans << endl;
    }
  }

  return 0;
}
0