結果
問題 | No.749 クエリ全部盛り |
ユーザー | ats5515 |
提出日時 | 2018-10-20 10:20:15 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 1,128 ms / 3,000 ms |
コード長 | 3,781 bytes |
コンパイル時間 | 1,735 ms |
コンパイル使用メモリ | 88,796 KB |
実行使用メモリ | 93,028 KB |
最終ジャッジ日時 | 2024-11-19 02:12:26 |
合計ジャッジ時間 | 8,382 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,820 KB |
testcase_01 | AC | 2 ms
6,816 KB |
testcase_02 | AC | 2 ms
6,816 KB |
testcase_03 | AC | 2 ms
6,820 KB |
testcase_04 | AC | 2 ms
6,820 KB |
testcase_05 | AC | 6 ms
6,820 KB |
testcase_06 | AC | 6 ms
6,820 KB |
testcase_07 | AC | 6 ms
6,816 KB |
testcase_08 | AC | 6 ms
6,816 KB |
testcase_09 | AC | 6 ms
6,816 KB |
testcase_10 | AC | 58 ms
6,820 KB |
testcase_11 | AC | 57 ms
6,816 KB |
testcase_12 | AC | 59 ms
6,816 KB |
testcase_13 | AC | 59 ms
6,816 KB |
testcase_14 | AC | 59 ms
6,816 KB |
testcase_15 | AC | 1,128 ms
92,908 KB |
testcase_16 | AC | 1,107 ms
93,028 KB |
testcase_17 | AC | 1,108 ms
92,896 KB |
testcase_18 | AC | 1,112 ms
93,024 KB |
testcase_19 | AC | 1,113 ms
92,908 KB |
ソースコード
#include <iostream> #include <vector> #include <map> #include <set> #include <queue> #include <string> #include <iomanip> #include <algorithm> #include <cmath> #include <stdio.h> using namespace std; int MOD = 1000000007; using uint = unsigned int; #define int long long int fs[1050100]; inline int fib(int l, int r) { int res = (fs[r] - fs[l]) % MOD; if (res < 0)res += MOD; return res; } template<class T> using V = vector<T>; template<class OP> struct SegTree { using D = typename OP::D; using L = typename OP::L; static constexpr auto e_d = OP::e_d; static constexpr auto e_l = OP::e_l; static constexpr auto op_dd = OP::op_dd; static constexpr auto op_dl = OP::op_dl; static constexpr auto op_ll = OP::op_ll; int sz, lg; //(2^lgに拡張後の)サイズ, lg V<D> d; V<L> lz; SegTree(int n) : SegTree(V<D>(n, e_d())) {} SegTree(V<D> first) { int n = (int)(first.size()); lg = 1; while ((1 << lg) < n) lg++; sz = 1 << lg; d = V<D>(2 * sz, e_d()); lz = V<L>(2 * sz, e_l()); for (int i = 0; i < n; i++) d[sz + i] = first[i]; for (int i = sz - 1; i >= 0; i--) { update(i); } } inline void all_add(int k, const L &x, int l, int r) { d[k] = op_dl(d[k], x, l, r); lz[k] = op_ll(lz[k], x); } inline void push(int &k, int l, int r) { all_add(2 * k, lz[k], l, (l + r) >> 1); all_add(2 * k + 1, lz[k], (l + r) >> 1, r); lz[k] = e_l(); } inline void update(int k) { d[k] = op_dd(d[2 * k], d[2 * k + 1]); } D sum(int a, int b, int l, int r, int k) { if (b <= l || r <= a) return e_d(); if (a <= l && r <= b) return d[k]; push(k, l, r); int mid = (l + r) / 2; return op_dd(sum(a, b, l, mid, 2 * k), sum(a, b, mid, r, 2 * k + 1)); } D sum(int a, int b) { return sum(a, b, 0, sz, 1); } void add(int a, int b, L x, int l, int r, int k) { //cerr << l << " " << r << endl; if (b <= l || r <= a) return; if (a <= l && r <= b) { all_add(k, x, l, r); return; } push(k, l, r); int mid = (l + r) / 2; add(a, b, x, l, mid, 2 * k); add(a, b, x, mid, r, 2 * k + 1); update(k); } void add(int a, int b, L x) { add(a, b, x, 0, sz, 1); } }; struct LZ { int update = -1; int mul = 1; int add = 0; int fa = 0; }; struct OP { using D = int; using L = LZ; static constexpr D e_d() { return 0; } static constexpr L e_l() { return L(); } static D op_dd(D l, D r) { return (l + r) % MOD; } static D op_dl(D l, const L &r, int le, int ri) { D d; int len = (ri - le); if (r.update == -1) { d = l; } else { d = (r.update*len) % MOD; } d = (d*r.mul) % MOD; d = (d + r.add * len) % MOD; d = (d + r.fa*fib(le, ri)) % MOD; return d; } static L op_ll(const L &l, const L &r) { if (r.update != -1) { return r; } else { L n; n.update = l.update; n.mul = (l.mul * r.mul) % MOD; n.add = (l.add * r.mul + r.add) % MOD; n.fa = (l.fa * r.mul + r.fa) % MOD; return n; } } }; signed main() { cin.tie(0); ios::sync_with_stdio(false); int N, Q; cin >> N >> Q; auto seg = SegTree<OP>(N); int q, l, r, k; fs[0] = 0; fs[1] = 0; fs[2] = 1; for (int i = 3; i <= N + 2; i++) { fs[i] = (fs[i - 1] + fs[i - 2]) % MOD; } for (int i = 1; i <= N + 2; i++) { fs[i] = (fs[i] + fs[i - 1]); } cerr << "OK" << endl; for (int i = 0; i < Q; i++) { cin >> q >> l >> r >> k; LZ lazy; if (q == 0) { int t = seg.sum(l, r + 1); t = (t * k) % MOD; cout << t << endl; } else if (q == 1) { lazy.update = k; seg.add(l, r + 1, lazy); } else if (q == 2) { lazy.add = k; seg.add(l, r + 1, lazy); } else if (q == 3) { lazy.mul = k; seg.add(l, r + 1, lazy); } else if (q == 4) { lazy.fa = k; seg.add(l, r + 1, lazy); } } /*for (int i = 0; i < N; i++) { cerr << seg.sum(i, i + 1) << " "; } cerr << endl; */ }