intquery(int node, int l, int r){ auto &cur = seg_arr[node]; if (l <= cur.left && cur.right <= r) { // be totally covered, just return as the end of the recursion return cur.data; } auto mid = (cur.left + cur.right) >> 1; int res = 0; if (l <= mid) { res = std::max(res, query(cur.lson, l, r)); } if (r > mid) { res = std::max(res, query(cur.rson, l, r)); } return res; }
voidmodify(int node, int l, int r, int val){ auto &cur = seg_arr[node]; if (cur.left >= l && cur.right <= r) { cur.data += val; cur.lazy_tag += val; return; }
// no return? It means it will search the child, push down before searching push_down(node); auto mid = (cur.left + cur.right) >> 1; if (l <= mid) { modify(cur.lson, l, r, val); } if (r > mid) { modify(cur.rson, l, r, val); } push_up(node); }
constint MAXN = 10000; int arr[MAXN]; classsegmentTree { structTreeNode { int left, right; int lson, rson; int lazy_tag; longlong data;
TreeNode(int left_ = 0, int right_ = 0, int lson_ = 0, int rson_ = 0, longlong data_ = 0) : left(left_), right(right_), lson(lson_), rson(rson_), data(data_) {} };
private: TreeNode seg_arr[4 * MAXN];
public: segmentTree() { // build the initial tree (all empty) std::memset(seg_arr, 0, sizeof(seg_arr)); }
/** * @brief Build the initial tree * * @param number The index of the tree (array: seg_arr) * @param s the left index * @param t the right index */ voidbuild(int number, int s, int t){ // build the tree seg_arr[number].left = s; seg_arr[number].right = t; seg_arr[number].lazy_tag = 0; seg_arr[number].lson = number << 1; seg_arr[number].rson = seg_arr[number].lson + 1;
if (s == t) { // finish the end, return seg_arr[number].data = arr[s]; return; }
// not finish, go deeper int mid = (s + t) / 2; build(seg_arr[number].lson, s, mid); build(seg_arr[number].rson, mid + 1, t);
// update the value of the father node push_up(number); }
/** * @brief update the value of the father node (Traceback the two son nodes) * * @param node father node index */ voidpush_up(int node){ auto &cur = seg_arr[node]; cur.data = std::max(seg_arr[cur.lson].data, seg_arr[cur.rson].data); }
/** * @brief Ask fot the maximum value of [l, r] * * @param node (begin with index 1), the seg_arr index * @param l the left index * @param r the right index * @return int */ intquery(int node, int l, int r){ auto &cur = seg_arr[node]; if (l <= cur.left && cur.right <= r) { // be totally covered, just return as the end of the recursion return cur.data; }
// the son will be get, thus update the lazy tag push_down(node);
auto mid = (cur.left + cur.right) >> 1; int res = std::numeric_limits<int>::min(); if (l <= mid) { res = std::max(res, query(cur.lson, l, r)); } if (r > mid) { res = std::max(res, query(cur.rson, l, r)); } return res; }
/** * @brief Update single value, be banned (it does not use lazy tag) * * @param node * @param pos * @param val */ voidupdateSingle(int node, int pos, int val){ auto &cur = seg_arr[node]; auto mid = (cur.left + cur.right) >> 1; if (cur.lson == cur.rson) { // find the leaf node, return! cur.data = val; return; } if (pos <= mid) { updateSingle(cur.lson, pos, val); } if (pos > mid) { updateSingle(cur.rson, pos, val); } push_up(node); }
/** * @brief push down the lazy tag (for only one layer) * * @param node */ voidpush_down(int node){ auto &cur = seg_arr[node]; if (cur.left == cur.right) { // for the leaf node, do not push down return; } if (cur.lazy_tag != 0) { seg_arr[cur.lson].data += cur.lazy_tag;// for the maximum value seg_arr[cur.rson].data += cur.lazy_tag; seg_arr[cur.lson].lazy_tag += cur.lazy_tag; seg_arr[cur.rson].lazy_tag += cur.lazy_tag; cur.lazy_tag = 0; } }
/** * @brief Add val for all in [l, r] * * @param node begin from index 1 * @param l * @param r * @param val */ voidmodify(int node, int l, int r, int val){ auto &cur = seg_arr[node]; if (cur.left >= l && cur.right <= r) { cur.data += val; cur.lazy_tag += val; return; }
// no return? It means it will search the child, push down before searching (update the lazy tag) push_down(node); auto mid = (cur.left + cur.right) >> 1; if (l <= mid) { modify(cur.lson, l, r, val); } if (r > mid) { modify(cur.rson, l, r, val); } push_up(node); } };
intmain(){ constint n = 10; segmentTree segTree; for (int i = 1; i <= n; ++i) { arr[i] = i; }
segTree.build(1, 1, n);
std::cout << "Initial maximum in range [1, 5]: " << segTree.query(1, 1, 5) << std::endl; std::cout << "Initial maximum in range [1, 3]: " << segTree.query(1, 1, 3) << std::endl;
segTree.modify(1, 2, 4, 10);
std::cout << "After modifying range [2, 4] by +10:" << std::endl; std::cout << "Maximum in range [1, 5]: " << segTree.query(1, 1, 5) << std::endl; std::cout << "Maximum in range [3, 3]: " << segTree.query(1, 3, 3) << std::endl;
segTree.modify(1, 3, 10, 22); std::cout << "After modifying range [3, 10] by +22:" << std::endl; std::cout << "Maximum in range [1, 5]: " << segTree.query(1, 1, 5) << std::endl; std::cout << "Maximum in range [3, 3]: " << segTree.query(1, 3, 3) << std::endl; std::cout << "Maximum in range [1, 10]: " << segTree.query(1, 1, 10) << std::endl; std::cout << "Maximum in range [6, 10]: " << segTree.query(1, 6, 10) << std::endl;
segTree.modify(1, 1, 10, 5); std::cout << "After modifying range [1, 10] by +5:" << std::endl; std::cout << "Maximum in range [1, 10]: " << segTree.query(1, 1, 10) << std::endl; std::cout << "Maximum in range [6, 10]: " << segTree.query(1, 6, 10) << std::endl;
constint MAXN = 100002; longlong arr[MAXN]; longlong n, q, m; structTreeNode { int left, right; int lson, rson; longlong lazy_tag_plus; longlong lazy_tag_mul; longlong data;
public: segmentTree() { // build the initial tree (all empty) std::memset(seg_arr, 0, sizeof(seg_arr)); }
/** * @brief Build the initial tree * * @param number The index of the tree (array: seg_arr) * @param s the left index * @param t the right index */ voidbuild(int number, int s, int t){ // build the tree seg_arr[number].left = s; seg_arr[number].right = t; seg_arr[number].lazy_tag_plus = 0; seg_arr[number].lazy_tag_mul = 1; seg_arr[number].lson = number << 1; seg_arr[number].rson = seg_arr[number].lson + 1;
if (s == t) { // finish the end, return seg_arr[number].data = (arr[s] % m + m) % m; return; }
// not finish, go deeper int mid = (s + t) / 2; build(seg_arr[number].lson, s, mid); build(seg_arr[number].rson, mid + 1, t);
// update the value of the father node push_up(number); }
/** * @brief update the value of the father node (Traceback the two son nodes) * * @param node father node index */ voidpush_up(int node){ auto &cur = seg_arr[node]; cur.data = (seg_arr[cur.lson].data + seg_arr[cur.rson].data) % m; }
/** * @brief Ask fot the maximum value of [l, r] * * @param node (begin with index 1), the seg_arr index * @param l the left index * @param r the right index * @return int */ longlongquery(int node, int l, int r){ auto &cur = seg_arr[node]; if (l <= cur.left && cur.right <= r) { // be totally covered, just return as the end of the recursion return (cur.data % m + m) % m; }
// the son will be get, thus update the lazy tag push_down(node);
auto mid = (cur.left + cur.right) >> 1; longlong res = 0; if (l <= mid) { res += query(cur.lson, l, r); res = (res % m + m) % m; } if (r > mid) { res += query(cur.rson, l, r); res = (res % m + m) % m; } return (res % m + m) % m; }
/** * @brief push down the lazy tag (for only one layer) * * @param node */ voidpush_down(int node){ auto &cur = seg_arr[node]; if (cur.left == cur.right) { // for the leaf node, do not push down return; } if (cur.lazy_tag_plus != 0 || cur.lazy_tag_mul != 1) { seg_arr[cur.lson].data = (seg_arr[cur.lson].data * cur.lazy_tag_mul % m + cur.lazy_tag_plus * (seg_arr[cur.lson].right - seg_arr[cur.lson].left + 1) % m) % m; seg_arr[cur.rson].data = (seg_arr[cur.rson].data * cur.lazy_tag_mul % m + cur.lazy_tag_plus * (seg_arr[cur.rson].right - seg_arr[cur.rson].left + 1) % m) % m;
seg_arr[cur.lson].lazy_tag_plus = (seg_arr[cur.lson].lazy_tag_plus * cur.lazy_tag_mul % m + cur.lazy_tag_plus) % m; seg_arr[cur.lson].lazy_tag_mul = seg_arr[cur.lson].lazy_tag_mul * cur.lazy_tag_mul % m;
seg_arr[cur.rson].lazy_tag_plus = (seg_arr[cur.rson].lazy_tag_plus * cur.lazy_tag_mul % m + cur.lazy_tag_plus) % m; seg_arr[cur.rson].lazy_tag_mul = seg_arr[cur.rson].lazy_tag_mul * cur.lazy_tag_mul % m;
cur.lazy_tag_plus = 0; cur.lazy_tag_mul = 1; } }
/** * @brief Add val for all in [l, r] * * @param node begin from index 1 * @param l * @param r * @param val */ voidmodify_plus(int node, int l, int r, longlong val){ val = (val % m + m) % m; auto &cur = seg_arr[node]; if (cur.left >= l && cur.right <= r) { cur.data = (cur.data + val * (cur.right - cur.left + 1) % m); cur.lazy_tag_plus = (cur.lazy_tag_plus + val) % m; return; }
// no return? It means it will search the child, push down before searching (update the lazy tag) push_down(node); auto mid = (cur.left + cur.right) >> 1; if (l <= mid) { modify_plus(cur.lson, l, r, val); } if (r > mid) { modify_plus(cur.rson, l, r, val); } push_up(node); }
voidmodify_mul(int node, int l, int r, longlong val){ val = (val % m + m) % m; auto &cur = seg_arr[node]; if (cur.left >= l && cur.right <= r) { cur.data = cur.data * val % m; cur.lazy_tag_mul = cur.lazy_tag_mul * val % m; cur.lazy_tag_plus = cur.lazy_tag_plus * val % m; return; }
// no return? It means it will search the child, push down before searching (update the lazy tag) push_down(node); auto mid = (cur.left + cur.right) >> 1; if (l <= mid) { modify_mul(cur.lson, l, r, val); } if (r > mid) { modify_mul(cur.rson, l, r, val); } push_up(node); } };
intmain(){ std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); std::cin >> n >> q >> m; for (int i = 1; i <= n; i++) { std::cin >> arr[i]; }
segmentTree seg; seg.build(1, 1, n); int op, x, y; longlong k; while (q--) { std::cin >> op >> x >> y; if (op == 1) { std::cin >> k; seg.modify_mul(1, x, y, k); } elseif (op == 2) { std::cin >> k; seg.modify_plus(1, x, y, k); } else { std::cout << seg.query(1, x, y) << "\n"; } } return0; }
constint MAXN = 50005; int op, X, D; int left_index;
structTreeNode { int left, right; int lson, rson; int full_tag; int lmax = 0, rmax = 0, max = 0; }; TreeNode seg_arr[MAXN << 2];
classsegmentTree { public: voidbuild(int number, int s, int t){ auto &cur = seg_arr[number]; cur.left = s; cur.right = t; cur.full_tag = 0; // 1 for make all empty, and 2 for make all full cur.lmax = cur.rmax = cur.max = t - s + 1;
if (s == t) { cur.max = 1; cur.lmax = 1; cur.rmax = 1; return; } cur.lson = number << 1; cur.rson = (number << 1) | 1;
int mid = (s + t) >> 1; build(cur.lson, s, mid); build(cur.rson, mid + 1, t); push_up(number); }
voidpush_up(int node){ auto &cur = seg_arr[node]; auto &ls = seg_arr[cur.lson]; auto &rs = seg_arr[cur.rson];
/** * @brief * * @param node * @param l * @param r * @param k * @return if no enough room, return 0, else, return the index of the empty room */ intquery(int node, int l, int r, int k){ auto &cur = seg_arr[node]; auto &ls = seg_arr[cur.lson]; auto &rs = seg_arr[cur.rson]; if (l == r) { return cur.max >= k ? l : 0; } // return 0 if there is no enough room
voidempty(int node, int l, int r){ if(D == 0){ return; }
auto &cur = seg_arr[node]; if (X <= l && X + D - 1 >= r) { // be totally covered cur.full_tag = 1; cur.lmax = cur.rmax = cur.max = cur.right - cur.left + 1; return; }
push_down(node); int mid = (l + r) >> 1; if (X <= mid) empty(cur.lson, l, mid); if (mid < X + D -1) empty(cur.rson, mid + 1, r); push_up(node); }
voidfull(int node, int l, int r){ if (D == 0) return; auto &cur = seg_arr[node]; if (X <= l && X + D - 1 >= r) { // be totally covered // make it all full cur.full_tag = 2; cur.lmax = cur.rmax = cur.max = 0; return; }
push_down(node); int mid = (l + r) >> 1; if (X <= mid) full(cur.lson, l, mid); if (mid < X + D -1) full(cur.rson, mid + 1, r); push_up(node); }
voidpush_down(int node){ auto &cur = seg_arr[node]; if (cur.full_tag == 0 || cur.left == cur.right) return;
auto &ls = seg_arr[cur.lson]; auto &rs = seg_arr[cur.rson];
if (cur.full_tag == 1) { // we need to make it all empty cur.full_tag = 0; ls.full_tag = 1; rs.full_tag = 1; ls.max = ls.rmax = ls.lmax = ls.right - ls.left + 1; rs.max = rs.rmax = rs.lmax = rs.right - rs.left + 1; }
elseif (cur.full_tag == 2) { // we need to make it all full cur.full_tag = 0; ls.full_tag = 2; rs.full_tag = 2; ls.max = ls.rmax = ls.lmax = 0; rs.max = rs.rmax = rs.lmax = 0; } } };
intmain(){ int N, M; std::cin >> N >> M; std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);
segmentTree sg; sg.build(1, 1, N);
while (M--) { std::cin >> op; if (op == 1) { std::cin >> D; left_index = sg.query(1, 1, N, D); if(left_index != 0){ X = left_index; // the segement needs to be filled is [left_index, left_index + D - 1]; sg.full(1,1,N); } std::cout << left_index << "\n"; } else { std::cin >> X >> D; sg.empty(1, 1,N); } } return0; }
structTreeNode { int left, right; int lson, rson; double sum_1; double sum_2;//平方和 double lazy_tag; }; TreeNode seg_arr[4 * MAXN];
classsegmentTree { public: /** * @brief Build the initial tree * * @param number The index of the tree (array: seg_arr) * @param s the left index * @param t the right index */ voidbuild(int number, int s, int t){ auto &cur = seg_arr[number]; cur.left = s; cur.right = t; cur.lson = number << 1; cur.rson = (number << 1) + 1;
// lazy add cur.lazy_tag = 0;
if (s == t) { // finish the end, return cur.sum_1 = arr[s]; cur.sum_2 = arr[s] * arr[s]; return; }
// not finish, go deeper int mid = (s + t) / 2; build(cur.lson, s, mid); build(cur.rson, mid + 1, t);
// update the value of the father node push_up(number); }
/** * @brief update the value of the father node (Traceback the two son nodes) * * @param node father node index */ voidpush_up(int node){ // update sum1 and sum2 auto &cur = seg_arr[node]; auto &ls = seg_arr[cur.lson]; auto &rs = seg_arr[cur.rson];
doublequery_sum(int node, int l, int r){ auto &cur = seg_arr[node]; if (l <= cur.left && r >= cur.right) { // be covered return cur.sum_1; }
push_down(node); int mid = (cur.left + cur.right) >> 1; double ans = 0; if (l <= mid) { // go to the left ans += query_sum(cur.lson, l, r); }
if (r > mid) { ans += query_sum(cur.rson, l, r); } return ans; }
doublequery_sum_square(int node, int l, int r){ auto &cur = seg_arr[node]; if (l <= cur.left && r >= cur.right) { // be covered return cur.sum_2; }
push_down(node); int mid = (cur.left + cur.right) >> 1; double ans = 0; if (l <= mid) { // go to the left ans += query_sum_square(cur.lson, l, r); }
if (r > mid) { ans += query_sum_square(cur.rson, l, r); } return ans; }
/** * @brief push down the lazy tag (for only one layer) * * @param node */ voidpush_down(int node){ auto &cur = seg_arr[node]; auto &ls = seg_arr[cur.lson]; auto &rs = seg_arr[cur.rson]; if (cur.left == cur.right) { // for the leaf node, do not push down return; } if (cur.lazy_tag != 0) { // for sum1, add directly ls.sum_2 += 2 * ls.sum_1 * cur.lazy_tag + (ls.right - ls.left + 1) * (cur.lazy_tag) * cur.lazy_tag; rs.sum_2 += 2 * rs.sum_1 * cur.lazy_tag + (rs.right - rs.left + 1) * (cur.lazy_tag) * cur.lazy_tag; ls.sum_1 += (ls.right - ls.left + 1) * cur.lazy_tag; rs.sum_1 += (rs.right - rs.left + 1) * cur.lazy_tag; ls.lazy_tag += cur.lazy_tag; rs.lazy_tag += cur.lazy_tag; cur.lazy_tag = 0; } }
/** * @brief Add val for all in [l, r] * * @param node begin from index 1 * @param l * @param r * @param val */ voidmodify(int node, int l, int r, double val){ auto &cur = seg_arr[node]; if (cur.left >= l && cur.right <= r) { // be covered cur.sum_2 += 2 * cur.sum_1 * val; cur.sum_2 += (cur.right - cur.left + 1) * val * val; cur.sum_1 += (cur.right - cur.left + 1) * (val); cur.lazy_tag += val; return; }
push_down(node); auto mid = (cur.left + cur.right) >> 1; if (l <= mid) { modify(cur.lson, l, r, val); }
if (r > mid) { modify(cur.rson, l, r, val); }
push_up(node); } };
intmain(){ // std::ios::sync_with_stdio(false); // std::cin.tie(0); // std::cout.tie(0); int N, M; std::cin >> N >> M; std::memset(arr, 0, sizeof(arr)); std::memset(seg_arr, 0, sizeof(seg_arr));
for (int i = 1; i <= N; i++) { std::cin >> arr[i]; }
segmentTree sg; sg.build(1, 1, N);
int op, x, y; double k; double sum = 0; double sum2 = 0; while (M--) { std::cin >> op >> x >> y; if (op == 1) { std::cin >> k; sg.modify(1, x, y, k); } elseif (op == 2) { std::cout << int(sg.query_sum(1, x, y) / (y - x + 1) * 100) << '\n'; } else { sum = sg.query_sum(1, x, y); sum2 = sg.query_sum_square(1, x, y); int length = (y - x + 1); double ret = sum / length; std::cout << int((sg.query_sum_square(1, x, y) / (y - x + 1) - ret * ret) * 100) << "\n"; } } return0; }