ivolff

ЕБАТЬ РАСПАРАЛЕЛИЛОСЬ

Oct 11th, 2020
2,433
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.75 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cmath>
  3. #include <climits>
  4. #include <execution>
  5. #include <iostream>
  6. #include <random>
  7. #include <vector>
  8. #include <variant>
  9.  
  10.  
  11. struct ComputeRequest {
  12.     int left;
  13.     int right;
  14. };
  15.  
  16. struct UpdateRequest {
  17.     int index;
  18.     int delta;
  19. };
  20.  
  21. using Request = std::variant<ComputeRequest, UpdateRequest>;
  22.  
  23. #define ll long long
  24.  
  25. std::vector<int> tree;
  26.  
  27. void init(const std::vector<int>& numbers) {
  28.     int sz = (1 << static_cast<int>(std::ceil(std::log2(numbers.size()))));
  29.     tree.resize((1 << (static_cast<int>(std::log2(sz)) + 1)) - 1, 0);
  30.     for (int i = sz - 1; i < sz * 2 - 1; ++i) {
  31.         if((i - sz + 1) < numbers.size())
  32.             tree[i] = numbers[i - sz + 1];
  33.         else
  34.             tree[i] = 0;
  35.     }
  36.     for (int i = sz - 2; i >= 0; --i) {
  37.         tree[i] = tree[i * 2 + 1] + tree[i * 2 + 2];
  38.     }
  39. }
  40.  
  41. void update(int curr_v, int dest_v, ll value, int lb, int rb, int tm) {
  42.     if (!((lb <= dest_v) && (dest_v < rb))) {
  43.         return;
  44.     }
  45.  
  46.     if (curr_v == dest_v + (tm - 1)) {
  47.         tree[curr_v] += value;
  48.         return;
  49.     }
  50.     int mid_b = lb + (rb - lb) / 2;
  51.     update(curr_v * 2 + 1, dest_v, value, lb, mid_b, tm);
  52.     update(curr_v * 2 + 2, dest_v, value, mid_b, rb, tm);
  53.     tree[curr_v] = tree[curr_v * 2 + 1] + tree[curr_v * 2 + 2];
  54. }
  55.  
  56. ll get(int indx, int rqL, int rqR, int L, int R)  {
  57.     if (rqL >= R || rqR   <= L)
  58.         return 0;
  59.     if (rqL <= L && rqR   >= R)
  60.         return tree[indx];
  61.     size_t mid_b = L + (R - L) / 2;
  62.     return get(indx * 2 + 1, rqL, rqR  , L, mid_b) +
  63.            get(indx * 2 + 2, rqL, rqR  , mid_b, R);
  64. }
  65.  
  66. std::vector<int> ProcessRequests(const std::vector<int>& numbers, const std::vector<Request>& requests) {
  67.     init(numbers);
  68.     int tm = numbers.size();
  69.     std::vector<int> ans(requests.size());
  70.     int i = 0, left = 0, right = 0, counter = 0;
  71.     while(i < requests.size()) {
  72.         left = i;
  73.         while (i < requests.size() && std::holds_alternative<ComputeRequest>(requests[i]))
  74.             i++;
  75.         right = i;
  76.         std::transform(std::execution::par, requests.begin()+left, requests.begin()+right,ans.begin()+counter,
  77.                        [tm](const Request& r) {
  78.                            return get(0, std::get<ComputeRequest>(r).left, std::get<ComputeRequest>(r).right,0, 1 << static_cast<int>(std::ceil(std::log2(tm))));
  79.                        });
  80.         counter += right - left;
  81.         if (i < requests.size()) {
  82.             auto req = std::get<UpdateRequest>(requests[i]);
  83.             i++;
  84.             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))));
  85.         }
  86.     }
  87.     ans.resize(counter);
  88.     return ans;
  89. }
Advertisement
Add Comment
Please, Sign In to add comment