結果
問題 | No.1000 Point Add and Array Add |
ユーザー | tsutaj |
提出日時 | 2020-02-24 01:21:46 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 577 ms / 2,000 ms |
コード長 | 5,085 bytes |
コンパイル時間 | 907 ms |
コンパイル使用メモリ | 74,716 KB |
実行使用メモリ | 19,052 KB |
最終ジャッジ日時 | 2024-10-11 01:09:16 |
合計ジャッジ時間 | 6,189 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 1 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 2 ms
5,248 KB |
testcase_08 | AC | 2 ms
5,248 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 2 ms
5,248 KB |
testcase_11 | AC | 1 ms
5,248 KB |
testcase_12 | AC | 4 ms
5,248 KB |
testcase_13 | AC | 3 ms
5,248 KB |
testcase_14 | AC | 5 ms
5,248 KB |
testcase_15 | AC | 4 ms
5,248 KB |
testcase_16 | AC | 351 ms
16,836 KB |
testcase_17 | AC | 316 ms
12,004 KB |
testcase_18 | AC | 523 ms
18,916 KB |
testcase_19 | AC | 521 ms
18,916 KB |
testcase_20 | AC | 234 ms
18,924 KB |
testcase_21 | AC | 577 ms
19,008 KB |
testcase_22 | AC | 374 ms
19,048 KB |
testcase_23 | AC | 574 ms
19,052 KB |
ソースコード
#include <algorithm> #include <cstdio> #include <vector> #include <utility> #include <tuple> #include <functional> using namespace std; using ll = long long int; // @category 繧サ繧ー繝。繝ウ繝域惠 (Segment Tree) // @title 驕�サカ莨晄眺繧サ繧ー繝。繝ウ繝域惠 (Lazy Segment Tree) template <typename MonoidType, typename OperatorType> struct LazySegmentTree { using MMtoM = function< MonoidType(MonoidType, MonoidType) >; using OOtoO = function< OperatorType(OperatorType, OperatorType) >; using MOtoM = function< MonoidType(MonoidType, OperatorType) >; using OItoO = function< OperatorType(OperatorType, int) >; // node, lazy, update flag (for lazy), identity element int n; vector<MonoidType> node; vector<OperatorType> lazy; vector<bool> need_update; MonoidType E0; OperatorType E1; // update / combine / lazy / accumulate function MOtoM upd_f; MMtoM cmb_f; OOtoO lzy_f; OItoO acc_f; void build(int m, vector<MonoidType> v = vector<MonoidType>()) { if(v != vector<MonoidType>()) m = v.size(); n = 1; while(n < m) n *= 2; node = vector<MonoidType>(2*n-1, E0); lazy = vector<OperatorType>(2*n-1, E1); need_update = vector<bool>(2*n-1, false); if(v != vector<MonoidType>()) { for(int i=0; i<m; i++) { node[n-1+i] = v[i]; } for(int i=n-2; i>=0; i--) { node[i] = cmb_f(node[2*i+1], node[2*i+2]); } } } // initialize LazySegmentTree() {} LazySegmentTree(int n_, MonoidType E0_, OperatorType E1_, MOtoM upd_f_, MMtoM cmb_f_, OOtoO lzy_f_, OItoO acc_f_, vector<MonoidType> v = vector<MonoidType>()) : E0(E0_), E1(E1_), upd_f(upd_f_), cmb_f(cmb_f_), lzy_f(lzy_f_), acc_f(acc_f_) { build(n_, v); } void eval(int k, int l, int r) { if(!need_update[k]) return; node[k] = upd_f(node[k], acc_f(lazy[k], r - l)); if(r - l > 1) { lazy[2*k+1] = lzy_f(lazy[2*k+1], lazy[k]); lazy[2*k+2] = lzy_f(lazy[2*k+2], lazy[k]); need_update[2*k+1] = need_update[2*k+2] = true; } lazy[k] = E1; need_update[k] = false; } void update(int a, int b, OperatorType x, int l, int r, int k) { eval(k, l, r); if(b <= l or r <= a) return; if(a <= l and r <= b) { lazy[k] = lzy_f(lazy[k], x); need_update[k] = true; eval(k, l, r); } else { int mid = (l + r) / 2; update(a, b, x, l, mid, 2*k+1); update(a, b, x, mid, r, 2*k+2); node[k] = cmb_f(node[2*k+1], node[2*k+2]); } } MonoidType query(int a, int b, int l, int r, int k) { if(b <= l or r <= a) return E0; eval(k, l, r); if(a <= l and r <= b) return node[k]; int mid = (l + r) / 2; MonoidType vl = query(a, b, l, mid, 2*k+1); MonoidType vr = query(a, b, mid, r, 2*k+2); return cmb_f(vl, vr); } // update [a, b)-th element (applied value, x) void update(int a, int b, OperatorType x) { update(a, b, x, 0, n, 0); } // range query for [a, b) MonoidType query(int a, int b) { return query(a, b, 0, n, 0); } void dump() { fprintf(stderr, "[lazy]\n"); for(int i=0; i<2*n-1; i++) { if(i == n-1) fprintf(stderr, "xxx "); if(lazy[i] == E1) fprintf(stderr, " E "); else fprintf(stderr, "%3d ", lazy[i]); } fprintf(stderr, "\n"); fprintf(stderr, "[node]\n"); for(int i=0; i<2*n-1; i++) { if(i == n-1) fprintf(stderr, "xxx "); if(node[i] == E0) fprintf(stderr, " E "); else fprintf(stderr, "%3d ", node[i]); } fprintf(stderr, "\n"); } }; int main() { int N, Q; scanf("%d%d", &N, &Q); vector<ll> A(N); for(int i=0; i<N; i++) scanf("%lld", &A[i]); vector< tuple<int, ll, ll> > queries; for(int i=0; i<Q; i++) { char c; ll x, y; scanf(" %c %lld%lld", &c, &x, &y); int t = (c == 'A' ? 1 : 2); queries.emplace_back(t, x, y); } reverse(queries.begin(), queries.end()); LazySegmentTree<ll, ll> seg(N, 0, 0, [](ll a, ll b) { return a + b; }, [](ll a, ll b) { return a + b; }, [](ll a, ll b) { return a + b; }, [](ll a, int x) { return a; }); vector<ll> B(N); for(int i=0; i<Q; i++) { int t; ll x, y; tie(t, x, y) = queries[i]; if(t == 1) { --x; B[x] += seg.query(x, x+1) * y; } if(t == 2) { --x; seg.update(x, y, 1); } } for(int i=0; i<N; i++) { B[i] += seg.query(i, i+1) * A[i]; } for(int i=0; i<N; i++) printf("%lld%c", B[i], " \n"[i + 1 == N]); return 0; }