結果
問題 | No.749 クエリ全部盛り |
ユーザー | ats5515 |
提出日時 | 2018-10-19 23:05:24 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 1,423 ms / 3,000 ms |
コード長 | 3,930 bytes |
コンパイル時間 | 812 ms |
コンパイル使用メモリ | 88,672 KB |
実行使用メモリ | 93,028 KB |
最終ジャッジ日時 | 2024-11-18 22:19:39 |
合計ジャッジ時間 | 9,402 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 1 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 | 7 ms
5,248 KB |
testcase_06 | AC | 7 ms
5,248 KB |
testcase_07 | AC | 7 ms
5,248 KB |
testcase_08 | AC | 7 ms
5,248 KB |
testcase_09 | AC | 7 ms
5,248 KB |
testcase_10 | AC | 75 ms
5,248 KB |
testcase_11 | AC | 75 ms
5,248 KB |
testcase_12 | AC | 75 ms
5,248 KB |
testcase_13 | AC | 75 ms
5,248 KB |
testcase_14 | AC | 75 ms
5,248 KB |
testcase_15 | AC | 1,413 ms
92,900 KB |
testcase_16 | AC | 1,409 ms
93,028 KB |
testcase_17 | AC | 1,418 ms
92,972 KB |
testcase_18 | AC | 1,418 ms
92,840 KB |
testcase_19 | AC | 1,423 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]; 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); } } void all_add(int k, L x, int l, int r) { d[k] = op_dl(d[k], x, l, r); lz[k] = op_ll(lz[k], x); } void push(int k, int l, int r) { int mid = (l + r) / 2; all_add(2 * k, lz[k], l, mid); all_add(2 * k + 1, lz[k], mid, r); lz[k] = e_l(); } 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); } }; //starry sky tree struct LZ { int add = 0; int mul = 1; int update = -1; 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; } //cerr << le << " " << ri << endl; //cerr << r.update << " " << r.mul << " " << r.add << " " << r.fa << " " << d <<endl; d = (d*r.mul) % MOD; d = (d + ((r.add * len) % MOD)) % MOD; d = (d + ((r.fa*fib(le, ri)) % MOD)) % MOD; return d; } static L op_ll(const L &l, const L &r) { L n; if (r.update != -1) { n = r; } else { n.update = l.update; n.mul = (l.mul*r.mul) % MOD; n.add = (((l.add * r.mul) % MOD) + r.add) % MOD; n.fa = (((l.fa * r.mul) % MOD) + 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; */ }