Advertisement
Guest User

Untitled

a guest
May 22nd, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.56 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cmath>
  4. #include <random>
  5. #include <ctime>
  6. using std::cin;
  7. using std::cout;
  8. using std::vector;
  9. std::mt19937 gen;
  10.  
  11. vector<int> precount_log;
  12. vector<int> precount_pow;
  13.  
  14. class FastRMQ {
  15.  public:
  16.     explicit FastRMQ(vector<int> &data);
  17.     int request(int l, int r);
  18.  private:
  19.     vector<int> start_data;
  20.     void precount_logparts();
  21.     int halflog;
  22.     vector<int> parttype;
  23.     vector<vector<int>> body;
  24.     vector<vector<vector<int>>> log_parts_answer;
  25. };
  26. FastRMQ::FastRMQ(vector<int> &d) : start_data(d) {
  27.     halflog = int(log2(start_data.size()) / 2);
  28.     int big = start_data[start_data.size() - 1] + 1;
  29.     while (start_data.size() % halflog != 0) {
  30.         start_data.push_back(big);
  31.     }
  32.     //предпосчёт логарифмов
  33.     for (int i = 0; i < start_data.size() + 1; ++i) {
  34.         precount_log.push_back(int(std::log2(i)));
  35.     }
  36.     for (int pow:precount_log) {
  37.         precount_pow.push_back(int(std::pow(2, pow)));
  38.     }
  39.     //предподсчёт кусков размера halflog
  40.     precount_logparts();
  41.  
  42.     for (int i = 0; i < start_data.size(); i += halflog) {
  43.         int type = 0;
  44.         for (int j = halflog - 2; j >= 0; --j) {
  45.             type = type * 2 + (1 + start_data[i + j + 1] - start_data[i + j]) / 2;
  46.         }
  47.         parttype.push_back(type);
  48.     }
  49.     //строим стандартный SparseTable
  50.     body.emplace_back();
  51.     for (int i = 0; i < start_data.size() / halflog; ++i) {
  52.         body[0].push_back(log_parts_answer[parttype[i]][0][halflog - 1] + start_data[i * halflog]);
  53.     }
  54.     for (int partsize = 2; partsize < (start_data.size() / halflog); partsize *= 2) {
  55.         body.emplace_back();
  56.         int size = body.size() - 1;
  57.         for (int i = 0; i < (start_data.size() / halflog) - partsize + 1; ++i) {
  58.             body[size].push_back(std::min(body[size - 1][i], body[size - 1][i + partsize / 2]));
  59.         }
  60.     }
  61. }
  62. void FastRMQ::precount_logparts() {
  63.     for (int number = 0; number < pow(2, halflog - 1); ++number) {
  64.         log_parts_answer.emplace_back();
  65.         vector<int> curr_vector(1, 0);
  66.         for (int counter = 0, localnumber = number; counter < halflog - 1; ++counter) {
  67.             curr_vector.push_back(curr_vector[curr_vector.size() - 1] - 1 + 2 * (localnumber % 2));
  68.             localnumber /= 2;
  69.         }
  70.         for (int l = 0; l < halflog; ++l) {
  71.             log_parts_answer[number].emplace_back();
  72.             int localmin = curr_vector[l];
  73.             for (int r = l; r < halflog; ++r) {
  74.                 localmin = std::min(localmin, curr_vector[r]);
  75.                 log_parts_answer[number][l].push_back(localmin);
  76.             }
  77.         }
  78.     }
  79. }
  80. int FastRMQ::request(int l, int r) {
  81.     if (l / halflog == r / halflog) {
  82.         return start_data[l - l % halflog] + log_parts_answer[parttype[l / halflog]][l % halflog][r - l];
  83.     } else {
  84.         int leftborlder = l / halflog + 1;
  85.         int rightborder = r / halflog - 1;
  86.         int middleanswer = 2e9;
  87.         int curlog = precount_log[rightborder - leftborlder + 1];
  88.         int max_size = precount_pow[rightborder - leftborlder + 1];
  89.         if (leftborlder <= rightborder) {
  90.             middleanswer = std::min(body[curlog][leftborlder], body[curlog][rightborder - max_size + 1]);
  91.         }
  92.         int leftanswer = start_data[l - l % halflog]
  93.             + log_parts_answer[parttype[leftborlder - 1]][l % halflog][halflog - 1 - l % halflog];
  94.         int rightanswer = start_data[r - r % halflog] + log_parts_answer[parttype[rightborder + 1]][0][r % halflog];
  95.         return std::min(std::min(leftanswer, rightanswer), middleanswer);
  96.     }
  97. }
  98.  
  99. int main() {
  100.     gen.seed(time(0));
  101.  
  102.     int n, m;
  103.     m = 10;
  104.     cin >> n;;
  105.  
  106.     vector<int> data;
  107.     int d = 0;
  108.     for (int i = 0; i < n; ++i) {
  109.         d += 1;
  110.         d -= 2 * gen() % 2;
  111.         data.push_back(d);
  112.     }
  113.     FastRMQ test(data);
  114.     for (int i = 0; i < m; ++i) {
  115.         int l, r;
  116.         r = 1 + gen() % (n - 1);
  117.         l = gen() % r;
  118.         int stupidans = 2e9;
  119.         for (int j = l; j <= r; ++j) {
  120.             stupidans = std::min(stupidans, data[j]);
  121.         }
  122.         int x = test.request(l, r);
  123.         if (x == stupidans) {
  124.             cout << "\nTEST PASSED:\nl=" << l << "\nr=" << r << "\nanswer=" << x;
  125.         } else {
  126.             cout << "\nTEST FAILED:\nl=" << l << "\nr=" << r << "\nn=" << n;
  127.             cout << "UDSCBUDnjavdnjcnsanvdnjdv\nirwvnjcljvkhqwbk\newkjhjewbkvuh\nkgwuehbefkvguw\neuwfhvbuwhe";
  128.         }
  129.  
  130.     }
  131.     return 0;
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement