結果
問題 | No.2333 Slime Structure |
ユーザー |
![]() |
提出日時 | 2023-05-28 13:47:39 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 180 ms / 3,000 ms |
コード長 | 6,680 bytes |
コンパイル時間 | 2,328 ms |
コンパイル使用メモリ | 207,616 KB |
最終ジャッジ日時 | 2025-02-13 10:18:49 |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 31 |
ソースコード
#include<bits/stdc++.h>using namespace std;using int64 = long long;const int mod = 998244353;const int64 infll = (1LL << 62) - 1;const int inf = (1 << 30) - 1;struct IoSetup {IoSetup() {cin.tie(nullptr);ios::sync_with_stdio(false);cout << fixed << setprecision(10);cerr << fixed << setprecision(10);}} iosetup;template< typename T1, typename T2 >ostream &operator<<(ostream &os, const pair< T1, T2 >& p) {os << p.first << " " << p.second;return os;}template< typename T1, typename T2 >istream &operator>>(istream &is, pair< T1, T2 > &p) {is >> p.first >> p.second;return is;}template< typename T >ostream &operator<<(ostream &os, const vector< T > &v) {for(int i = 0; i < (int) v.size(); i++) {os << v[i] << (i + 1 != v.size() ? " " : "");}return os;}template< typename T >istream &operator>>(istream &is, vector< T > &v) {for(T &in : v) is >> in;return is;}template< typename T1, typename T2 >inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }template< typename T1, typename T2 >inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }template< typename T = int64 >vector< T > make_v(size_t a) {return vector< T >(a);}template< typename T, typename... Ts >auto make_v(size_t a, Ts... ts) {return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));}template< typename T, typename V >typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {t = v;}template< typename T, typename V >typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {for(auto &e : t) fill_v(e, v);}template< typename F >struct FixPoint : F {explicit FixPoint(F &&f) : F(forward< F >(f)) {}template< typename... Args >decltype(auto) operator()(Args &&... args) const {return F::operator()(*this, forward< Args >(args)...);}};template< typename F >inline decltype(auto) MFP(F &&f) {return FixPoint< F >{forward< F >(f)};}#line 1 "structure/segment-tree/segment-tree.hpp"/*** @brief Segment Tree(セグメント木)* @docs docs/segment-tree.md*/template< typename T, typename F >struct SegmentTree {int n, sz;vector< T > seg;const F f;const T ti;SegmentTree() = default;explicit SegmentTree(int n, const F f, const T &ti) : n(n), f(f), ti(ti) {sz = 1;while(sz < n) sz <<= 1;seg.assign(2 * sz, ti);}explicit SegmentTree(const vector< T > &v, const F f, const T &ti) :SegmentTree((int) v.size(), f, ti) {build(v);}void build(const vector< T > &v) {assert(n == (int) v.size());for(int k = 0; k < n; k++) seg[k + sz] = v[k];for(int k = sz - 1; k > 0; k--) {seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);}}void set(int k, const T &x) {k += sz;seg[k] = x;while(k >>= 1) {seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);}}T get(int k) const {return seg[k + sz];}T operator[](const int &k) const {return get(k);}void apply(int k, const T &x) {k += sz;seg[k] = f(seg[k], x);while(k >>= 1) {seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);}}T prod(int l, int r) const {T L = ti, R = ti;for(l += sz, r += sz; l < r; l >>= 1, r >>= 1) {if(l & 1) L = f(L, seg[l++]);if(r & 1) R = f(seg[--r], R);}return f(L, R);}T all_prod() const {return seg[1];}template< typename C >int find_first(int l, const C &check) const {if(l >= n) return n;l += sz;T sum = ti;do {while((l & 1) == 0) l >>= 1;if(check(f(sum, seg[l]))) {while(l < sz) {l <<= 1;auto nxt = f(sum, seg[l]);if(not check(nxt)) {sum = nxt;l++;}}return l + 1 - sz;}sum = f(sum, seg[l++]);} while((l & -l) != l);return n;}template< typename C >int find_last(int r, const C &check) const {if(r <= 0) return -1;r += sz;T sum = ti;do {r--;while(r > 1 and (r & 1)) r >>= 1;if(check(f(seg[r], sum))) {while(r < sz) {r = (r << 1) + 1;auto nxt = f(seg[r], sum);if(not check(nxt)) {sum = nxt;r--;}}return r - sz;}sum = f(seg[r], sum);} while((r & -r) != r);return -1;}};template< typename T, typename F >SegmentTree< T, F > get_segment_tree(int N, const F &f, const T &ti) {return SegmentTree{N, f, ti};}template< typename T, typename F >SegmentTree< T, F > get_segment_tree(const vector< T > &v, const F &f, const T &ti) {return SegmentTree{v, f, ti};}int main() {int N;cin >> N;vector< int64 > A(N), B(N);for(int i = 0; i < N; i++) {cin >> A[i] >> B[i];}int Q;cin >> Q;vector< int64 > T(Q), L(Q), R(Q);for(int i = 0; i < Q; i++) {cin >> T[i] >> L[i] >> R[i];--L[i];}auto pt = L;for(int i = 0; i < Q; i++) {if(T[i] == 1) {pt.emplace_back(L[i] + 1);} else {pt.emplace_back(R[i]);}}{int64 sum = 0;pt.emplace_back(sum);for (int i = 0; i < N; i++) {sum += B[i];pt.emplace_back(sum);}}sort(pt.begin(), pt.end());pt.erase(unique(pt.begin(), pt.end()), pt.end());struct Node {int64 ans, all, left, right, length;Node() : ans(-infll), all(0), left(-infll), right(-infll), length(0) {}Node(int64 val, int64 len) {length = len;all = val * length;ans = left = right = (val > 0 ? all : val);}Node operator+(const Node &s) const {Node ret;ret.length = length + s.length;ret.ans = max({ans, s.ans, right + s.left});ret.all = all + s.all;ret.left = max(left, all + s.left);ret.right = max(s.right, right + s.all);return ret;}};auto F = [](const Node &a, const Node &b) { return a + b; };vector< Node > before(pt.size());{int64 sum = 0;int pre = 0;for(int i = 0; i < N; i++) {sum += B[i];int nxt = pre;while(nxt < pt.size() and pt[nxt] < sum) {before[nxt] = Node(A[i], pt[nxt + 1] - pt[nxt]);++nxt;}pre = nxt;}}auto seg = get_segment_tree(before, F, Node());for(int i = 0; i < Q; i++) {L[i] = lower_bound(pt.begin(), pt.end(), L[i]) - pt.begin();if(T[i] == 1) {seg.set(L[i], Node(R[i], 1));} else {R[i] = lower_bound(pt.begin(), pt.end(), R[i]) - pt.begin();cout << seg.prod(L[i], R[i]).ans << "\n";}}}