ivolff

async DO1

Oct 8th, 2020 (edited)
969
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.16 KB | None | 0 0
  1. #include "profile.h"
  2. #include <algorithm>
  3. #include <execution>
  4. #include <random>
  5. #include <iostream>
  6. #include <vector>
  7. #include <cmath>
  8.  
  9. #define ll long long
  10.  
  11. std::mt19937 generator;
  12.  
  13. int counter = 0;
  14.  
  15. struct Request {
  16.     int left;
  17.     int right;
  18.  
  19.     Request(int size){
  20.         left = std::uniform_int_distribution(0, size - 1)(generator);
  21.         right = std::uniform_int_distribution(left, size - 1)(generator);
  22.     }
  23.  
  24.     Request(int L, int R){
  25.         left = L;
  26.         right = R;
  27.     }
  28. };
  29.  
  30. struct node{
  31. public:
  32.     long long L, R, val;
  33.  
  34.     node(int L = -1, int R = -1, long long val = INT64_MAX){
  35.         this->L = L;
  36.         this->R = R;
  37.         this->val = val;
  38.     }
  39.  
  40.     ~node() = default;
  41. };
  42.  
  43. std::vector<node> tree;
  44.  
  45. long long init_node(int indx, int L, int R, const std::vector<long long>& init_array){
  46.     if (L == R) {
  47.         if (counter < init_array.size())
  48.             tree[indx] = {L, R, init_array[counter]};
  49.         else
  50.             tree[indx] = {L, R, INT64_MAX};
  51.         counter++;
  52.         return tree[indx].val;
  53.     }
  54.     long long l = init_node(indx * 2 + 1, L,L + (R - L) / 2 , init_array);
  55.     long long r = init_node(indx * 2 + 2, L + (R - L) / 2  + 1, R, init_array);
  56.     tree[indx] = node(L,R, std::min(l,r));
  57.     return tree[indx].val;
  58. }
  59.  
  60. void init(const std::vector<long long>& init_array) {
  61.     int n = log2(init_array.size());
  62.     if ( 1 << n != init_array.size())
  63.         n ++;
  64.     int K = 1 << n;
  65.     tree.resize(K*2 - 1);
  66.     auto it = tree.rbegin();
  67.     int i = 0;
  68.     long long a = init_node(0, 0, K - 1, init_array);
  69.     tree[0] = {0, K - 1, a};
  70. }
  71.  
  72. long long gets(int indx, int L, int R) {
  73.     if (R >= tree[indx].R && L <= tree[indx].L)
  74.         return tree[indx].val;
  75.     if (R < tree[indx].L || L > tree[indx].R)
  76.         return INT64_MAX;
  77.     return std::min(gets(indx * 2 + 1, L, R), gets(indx * 2 + 2, L, R));
  78. }
  79.  
  80. long long get(Request req, int indx = 0) {
  81.     auto L = req.left, R = req.right;
  82.     if (R >= tree[indx].R && L <= tree[indx].L)
  83.         return tree[indx].val;
  84.     if (R < tree[indx].L || L > tree[indx].R)
  85.         return INT64_MAX;
  86.     return std::min(gets(indx * 2 + 1, L, R), gets(indx * 2 + 2, L, R));
  87. }
  88.  
  89.  
  90. std::vector<ll> ProcessRequests(const std::vector<ll>& numbers, const std::vector<Request>& requests){
  91.     std::vector<ll> ans(requests.size());
  92.     init(numbers);
  93.     std::transform(std::execution::par, requests.begin(), requests.end(), ans.begin(), [](Request r){return get(r);});
  94.     return ans;
  95.  
  96. }
  97.  
  98. std::vector<ll> ProcessRequestsOld(const std::vector<ll>& numbers, const std::vector<Request>& requests){
  99.     std::vector<ll> ans;
  100.     init(numbers);
  101.     for(auto el: requests){
  102.         ans.push_back(get(el));
  103.     }
  104.     return ans;
  105. }
  106.  
  107. int main(){
  108.     ll N= 100000000, R = 10000000;
  109.     std::vector<ll> num(N);
  110.     const std::vector<Request> request(R, N);
  111.     for(ll i = 0; i < N; i++){
  112.         num[i] = std::uniform_int_distribution(0, 1000000)(generator);
  113.     }
  114.     {
  115.         LOG_DURATION("Old");
  116.         ProcessRequestsOld(num, request);
  117.     }
  118.     tree.clear();
  119.     {
  120.         LOG_DURATION("New");
  121.         ProcessRequests(num, request);
  122.     }
  123. }
Add Comment
Please, Sign In to add comment