提交时间:2024-01-04 13:25:22

运行 ID: 119140

#include<bits/stdc++.h> using namespace std; long DIVISOR = 10007; class TreeNode { private: long ele, addtag, multitag; size_t l, r, lson, rson; TreeNode(long e = 0) : ele(e), addtag(0), multitag(1), l(0), r(0), lson(-1), rson(-1) {} public: friend class SegmentTree; }; class SegmentTree { public: SegmentTree(const vector<long>& vec){ nodes.push_back(TreeNode()); _build(vec, 0, 0, vec.size()); } long query(size_t l, size_t r, size_t pos = 0){ if(nodes[pos].l >= l && nodes[pos].r <= r)return nodes[pos].ele; _pushdown(pos); long res(0); if(nodes[nodes[pos].lson].r > l) (res += query(l, r, nodes[pos].lson)) %= DIVISOR; if (nodes[nodes[pos].rson].l < r) (res += query(l, r, nodes[pos].rson)) %= DIVISOR; return res; } void add(size_t l, size_t r, long val, size_t pos = 0) { if (nodes[pos].l >= l && nodes[pos].r <= r) { (nodes[pos].ele += val * (nodes[pos].r - nodes[pos].l)) %= DIVISOR; (nodes[pos].addtag += val) %= DIVISOR; return; } _pushdown(pos); if (nodes[nodes[pos].lson].r > l) add(l, r, val, nodes[pos].lson); if (nodes[nodes[pos].rson].l < r) add(l, r, val, nodes[pos].rson); _pushup(pos); } void multi(size_t l, size_t r, long val, size_t pos = 0) { if (nodes[pos].l >= l && nodes[pos].r <= r) { (nodes[pos].ele *= val) %= DIVISOR; (nodes[pos].addtag *= val) %= DIVISOR; (nodes[pos].multitag *= val) %= DIVISOR; return; } _pushdown(pos); if (nodes[nodes[pos].lson].r > l) multi(l, r, val, nodes[pos].lson); if (nodes[nodes[pos].rson].l < r) multi(l, r, val, nodes[pos].rson); _pushup(pos); } private: vector<TreeNode> nodes; void _pushdown(size_t pos) { TreeNode& lson(nodes[nodes[pos].lson]); lson.ele = (lson.ele * nodes[pos].multitag + nodes[pos].addtag * (lson.r - lson.l)) % DIVISOR; lson.addtag = (lson.addtag * nodes[pos].multitag + nodes[pos].addtag) % DIVISOR; lson.multitag = (lson.multitag * nodes[pos].multitag) % DIVISOR; TreeNode& rson(nodes[nodes[pos].rson]); rson.ele = (rson.ele * nodes[pos].multitag + nodes[pos].addtag * (rson.r - rson.l)) % DIVISOR; rson.addtag = (rson.addtag * nodes[pos].multitag + nodes[pos].addtag) % DIVISOR; rson.multitag = (rson.multitag * nodes[pos].multitag) % DIVISOR; nodes[pos].addtag = 0, nodes[pos].multitag = 1; } void _pushup(size_t pos) { if (nodes[pos].r - nodes[pos].l > 1) nodes[pos].ele = (nodes[nodes[pos].lson].ele + nodes[nodes[pos].rson].ele) % DIVISOR; } void _build(const vector<long>& vec, size_t pos, size_t l, size_t r) { nodes[pos].l = l, nodes[pos].r = r; if (r - l == 1) { nodes[pos].ele = vec[l] % DIVISOR; return; } nodes[pos].lson = nodes.size(); nodes.push_back(TreeNode()); _build(vec, nodes[pos].lson, l, (l + r) >> 1); nodes[pos].rson = nodes.size(); nodes.push_back(TreeNode()); _build(vec, nodes[pos].rson, (l + r) >> 1, r); _pushup(pos); } }; int main() { ios::sync_with_stdio(false); cin.tie(0); long N(0); cin >> N; vector<long> nums(N); for (vector<long>::iterator i(nums.begin()); i != nums.end(); ++i) cin >> *i; SegmentTree tree(nums); for (long k(0), l(0), r(0), v(0); N--; ) { cin >> k >> l >> r >> v; --l; if (k == 0) tree.add(l, r, v % DIVISOR); if (k == 1) tree.multi(l, r, v % DIVISOR); if (k == 2) cout << tree.query(r - 1, r) << endl; } return 0; }