Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <cmath>
- #include <climits>
- #include <execution>
- #include <iostream>
- #include <random>
- #include <vector>
- #include <variant>
- struct ComputeRequest {
- int left;
- int right;
- };
- struct UpdateRequest {
- int index;
- int delta;
- };
- using Request = std::variant<ComputeRequest, UpdateRequest>;
- #define ll long long
- std::vector<int> tree;
- void init(const std::vector<int>& numbers) {
- int sz = (1 << static_cast<int>(std::ceil(std::log2(numbers.size()))));
- tree.resize((1 << (static_cast<int>(std::log2(sz)) + 1)) - 1, 0);
- for (int i = sz - 1; i < sz * 2 - 1; ++i) {
- if((i - sz + 1) < numbers.size())
- tree[i] = numbers[i - sz + 1];
- else
- tree[i] = 0;
- }
- for (int i = sz - 2; i >= 0; --i) {
- tree[i] = tree[i * 2 + 1] + tree[i * 2 + 2];
- }
- }
- void update(int curr_v, int dest_v, ll value, int lb, int rb, int tm) {
- if (!((lb <= dest_v) && (dest_v < rb))) {
- return;
- }
- if (curr_v == dest_v + (tm - 1)) {
- tree[curr_v] += value;
- return;
- }
- int mid_b = lb + (rb - lb) / 2;
- update(curr_v * 2 + 1, dest_v, value, lb, mid_b, tm);
- update(curr_v * 2 + 2, dest_v, value, mid_b, rb, tm);
- tree[curr_v] = tree[curr_v * 2 + 1] + tree[curr_v * 2 + 2];
- }
- ll get(int indx, int rqL, int rqR, int L, int R) {
- if (rqL >= R || rqR <= L)
- return 0;
- if (rqL <= L && rqR >= R)
- return tree[indx];
- size_t mid_b = L + (R - L) / 2;
- return get(indx * 2 + 1, rqL, rqR , L, mid_b) +
- get(indx * 2 + 2, rqL, rqR , mid_b, R);
- }
- std::vector<int> ProcessRequests(const std::vector<int>& numbers, const std::vector<Request>& requests) {
- init(numbers);
- int tm = numbers.size();
- std::vector<int> ans(requests.size());
- int i = 0, left = 0, right = 0, counter = 0;
- while(i < requests.size()) {
- left = i;
- while (i < requests.size() && std::holds_alternative<ComputeRequest>(requests[i]))
- i++;
- right = i;
- std::transform(std::execution::par, requests.begin()+left, requests.begin()+right,ans.begin()+counter,
- [tm](const Request& r) {
- return get(0, std::get<ComputeRequest>(r).left, std::get<ComputeRequest>(r).right,0, 1 << static_cast<int>(std::ceil(std::log2(tm))));
- });
- counter += right - left;
- if (i < requests.size()) {
- auto req = std::get<UpdateRequest>(requests[i]);
- i++;
- update(0,req.index, req.delta, 0, 1 << static_cast<int>(std::ceil(std::log2(tm))), 1 << static_cast<int>(std::ceil(std::log2(tm))));
- }
- }
- ans.resize(counter);
- return ans;
- }
Advertisement
Add Comment
Please, Sign In to add comment