#include #include #include #include #include #include #include #include #include #include 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 using V = vector; template 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; V lz; SegTree(int n) : SegTree(V(n, e_d())) {} SegTree(V first) { int n = (int)(first.size()); lg = 1; while ((1 << lg) < n) lg++; sz = 1 << lg; d = V(2 * sz, e_d()); lz = V(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 <> N >> Q; auto seg = SegTree(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; */ }