Advertisement
Guest User

Untitled

a guest
Dec 14th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.79 KB | None | 0 0
  1. #include <iostream>
  2. #include <random>
  3. #include <array>
  4. #include <algorithm>
  5. #include <functional>
  6. #include "utils.h"
  7.  
  8. using namespace std;
  9.  
  10. class BinsearchSolver {
  11. public:
  12. BinsearchSolver(const vector<uint64_t> &arr, string label) : arr_(arr), label_(label) {
  13. }
  14.  
  15. virtual void PreProcess() {}
  16.  
  17. virtual bool Query(uint64_t q) = 0;
  18.  
  19. void Process(uint64_t q) {
  20. timer_.Start();
  21.  
  22. bool res;
  23. // auto getter = [this, &res, q]() {
  24. // res = Query(q);
  25. // };
  26.  
  27. //sum_cache_misses += profiler.RunAndGetCacheMisses(getter);
  28. res = Query(q);
  29. timer_.Finish();
  30. yes_ += res;
  31. queries_count_++;
  32. results_.push_back(res);
  33. }
  34.  
  35. string get_label() const {
  36. return label_;
  37. }
  38.  
  39. void OutputResults(ostream &out) const {
  40. cerr << "Timer output for " << label_ << ":" << endl;
  41. cerr << "Percent of YES answer " << yes_ * 1.0 / queries_count_ << endl;
  42. cerr << "||||||||||Elapsed time for all queries : " << timer_.GetResult() << "ns" << endl;
  43. cerr << "||||||||||Average time for one binsearch : " << timer_.GetResult() * 1.0 / results_.size() << "ns"
  44. << endl;
  45. // cerr << "||||||||||Cache misses for all queries : " << sum_cache_misses << endl;
  46. // cerr << "||||||||||Average misses on one query: " << (sum_cache_misses * 1.0 / results_.size()) << endl;
  47.  
  48.  
  49. for (const auto &el : results_) {
  50. out << el << " ";
  51. }
  52. out << endl;
  53. }
  54.  
  55. virtual ~BinsearchSolver() {}
  56.  
  57. private:
  58. int64_t sum_cache_misses = 0;
  59. int yes_ = 0;
  60. int queries_count_ = 0;
  61. Timer timer_;
  62. vector<int> results_;
  63. protected:
  64. const vector<uint64_t> &arr_;
  65. string label_;
  66. };
  67.  
  68. class SqrtBinsearchSolver : public BinsearchSolver {
  69. public:
  70. SqrtBinsearchSolver(const vector<uint64_t> &arr, string label) : BinsearchSolver(arr, label) {
  71. PreProcess();
  72. }
  73.  
  74. void PreProcess() override {
  75. sq_ = sqrt(arr_.size());
  76. layout_.reserve(sq_);
  77. int index = 0;
  78. while (index < arr_.size()) {
  79. layout_.push_back(arr_[index]);
  80. index += sq_;
  81. }
  82. cerr << "Sqrt Layout has been built" << endl;
  83. }
  84.  
  85. bool TryFindInSubarray(int l, int r, uint64_t q) {
  86. auto it = lower_bound(arr_.begin() + l, arr_.begin() + r + 1, q);
  87. if (it == arr_.begin() + r + 1) {
  88. return false;
  89. }
  90. return (*it == q);
  91. }
  92.  
  93. bool TryFindInPart(int i, uint64_t q) {
  94. return TryFindInSubarray(i * sq_, min((i + 1) * sq_ - 1, (int) arr_.size() - 1), q);
  95. }
  96.  
  97. bool Query(uint64_t q) override {
  98. auto sq_find = lower_bound(layout_.begin(), layout_.end(), q);
  99. auto ind = sq_find - layout_.begin();
  100. if (ind == layout_.size()) {
  101. return TryFindInPart(layout_.size() - 1, q);
  102. }
  103. if (*sq_find == q) {
  104. return true;
  105. }
  106. if (ind == 0) {
  107. return false;
  108. }
  109. return TryFindInPart(ind - 1, q);
  110. }
  111.  
  112. virtual ~SqrtBinsearchSolver() {}
  113.  
  114. private:
  115. int sq_ = -1;
  116. std::vector<uint64_t> layout_;
  117. };
  118.  
  119. class DefaultBinsearchSolver : public BinsearchSolver {
  120. public:
  121. DefaultBinsearchSolver(const vector<uint64_t> &arr, string label) : BinsearchSolver(arr, label) {
  122. }
  123.  
  124. bool Query(uint64_t q) override {
  125. auto res_it = std::lower_bound(arr_.begin(), arr_.end(), q);
  126. if (res_it != arr_.end()) {
  127. return (*res_it) == q;
  128. }
  129. return false;
  130. }
  131.  
  132. virtual ~DefaultBinsearchSolver() {}
  133.  
  134. };
  135.  
  136. class BTreeBinsearchSolver : public BinsearchSolver {
  137. public:
  138. BTreeBinsearchSolver(const vector<uint64_t> &arr, string label, int b) : BinsearchSolver(arr, label), b_(b) {
  139. PreProcess();
  140. }
  141.  
  142. void PreProcess() override {
  143. layout_.resize(arr_.size());
  144. int cur_arr_id_ = 0;
  145. int cur_v = 1;
  146. DfsInorder(cur_v, cur_arr_id_);
  147. cerr << "BTree Layout has been built" << endl;
  148. }
  149.  
  150. void DfsInorder(int cur_v, int &cur_arr_id) {
  151. if (cur_v * 1ll * (b_) <= arr_.size()) {
  152. auto ver = cur_v * b_;
  153. for (int i = 0; i < b_ - 1; i++) {
  154. DfsInorder(ver, cur_arr_id);
  155. layout_.at(cur_v - 1) = arr_.at(cur_arr_id++);
  156. cur_v++;
  157. ver += b_ - 1;
  158. }
  159. DfsInorder(ver, cur_arr_id);
  160. } else {
  161. int cnt = 0;
  162. while (cnt < b_ - 1 && cur_v <= arr_.size()) {
  163. layout_.at(cur_v - 1) = arr_.at(cur_arr_id++);
  164. cur_v++;
  165. cnt++;
  166. }
  167. }
  168. }
  169.  
  170. bool Query(uint64_t q) override {
  171. int cur_v = 1;
  172. int cnt = 0;
  173. int n = arr_.size();
  174. while (cur_v <= n) {
  175. cnt++;
  176. int l = cur_v - 1;
  177. int r = min(n - 1, l + b_ - 2);
  178. if (BinsearchInplace(l, r, q)) {
  179. return true;
  180. }
  181. uint64_t new_cur_v = (b_) * (cur_v + l) - l;
  182. if (new_cur_v > n) {
  183. break;
  184. }
  185. cur_v = new_cur_v;
  186. }
  187. return false;
  188. }
  189.  
  190. inline bool BinsearchInplace(int &l, int r, uint64_t q) {
  191. if (r - l <= 8) {
  192. int cur = 0;
  193. for (int i = l; i <= r; i++, cur++) {
  194. if (layout_[i] == q) {
  195. return true;
  196. }
  197. if (layout_[i] > q) {
  198. l = cur;
  199. return false;
  200. }
  201. }
  202. l = cur;
  203. return false;
  204. }
  205. auto l_val = layout_[l];
  206. if (l_val == q) {
  207. return true;
  208. }
  209. auto r_val = layout_[r];
  210. if (r_val == q) {
  211. return true;
  212. }
  213. if (l_val > q) {
  214. l = 0;
  215. return false;
  216. }
  217. if (r_val < q) {
  218. l = r - l + 1;
  219. return false;
  220. }
  221. int st_l = l;
  222. while (r - l > 1) {
  223. int m = (l + r) / 2;
  224. auto val = layout_[m];
  225. if (val == q) {
  226. return true;
  227. }
  228. if (val < q) {
  229. l = m;
  230. } else {
  231. r = m;
  232. }
  233. }
  234. l = l - st_l + 1;
  235. return false;
  236. }
  237.  
  238. virtual ~BTreeBinsearchSolver() {}
  239.  
  240. private:
  241. vector<uint64_t> layout_;
  242. int b_;
  243. };
  244.  
  245. class VanEmdeBoasSolver : public BinsearchSolver {
  246. public:
  247. VanEmdeBoasSolver(const vector<uint64_t> &arr, string label) : BinsearchSolver(arr, label) {
  248. PreProcess();
  249. }
  250.  
  251. void PreProcess() override {
  252. lg_ = Log2(arr_.size());
  253. layout_.resize(1 << lg_);
  254. std::copy(arr_.begin(), arr_.end(), layout_.begin() + 1);
  255. for (int i = arr_.size() + 1; i < layout_.size(); i++) {
  256. layout_[i] = arr_.back();
  257. }
  258. d_.resize(lg_ + 1);
  259. tt_.resize(lg_ + 1);
  260. pos_.resize(lg_ + 2);
  261. tmp_.resize(sqrt(layout_.size()));
  262. PrepareLayout(1, layout_.size() - 1, 1, lg_);
  263. cerr << "VanEmdeBoas Layout has been built" << endl;
  264. }
  265.  
  266. int Log2(int val) {
  267. int cnt = 30;
  268. while (!((1 << cnt) & val)) {
  269. cnt--;
  270. }
  271. return (cnt + 1);
  272. }
  273.  
  274. int CountOfDiv2(int val) {
  275. int cnt = 0;
  276. while (!(val & 1)) {
  277. val >>= 1;
  278. cnt++;
  279. }
  280. return cnt;
  281. }
  282.  
  283. void PrepareLayout(int l, int r, int h, int log_len) {
  284. if (log_len == 1) {
  285. return;
  286. }
  287. int top_log = log_len / 2;
  288. int bottom_log = log_len - top_log;
  289. int cnt_top = (1 << top_log) - 1;
  290. int cnt_bottom = (1 << bottom_log) - 1;
  291.  
  292. int layout_iter = r;
  293. int tmp_iter = cnt_top - 1;
  294. for (int i = r; i >= l; i--) {
  295. if (log_len - CountOfDiv2(i - l + 1) <= top_log) {
  296. tmp_[tmp_iter--] = layout_[i];
  297. } else {
  298. layout_[layout_iter--] = layout_[i];
  299. }
  300. }
  301. std::copy(tmp_.begin(), tmp_.begin() + cnt_top, layout_.begin() + l);
  302. PrepareLayout(l, l + cnt_top - 1, h, top_log);
  303. for (int i = 0; i <= cnt_top ; i++) {
  304. PrepareLayout(l + cnt_top + i * cnt_bottom, l + cnt_top + (i + 1) * cnt_bottom - 1, h + top_log,
  305. bottom_log);
  306. }
  307. tt_[h + top_log] = log_len;
  308. d_[h + top_log] = h;
  309. }
  310. bool Query(uint64_t q) override {
  311. int bfs_pos = 1;
  312. int d = 1;
  313. pos_[1] = 1;
  314. for (int i = 1; i <= lg_; i++) {
  315. auto val = layout_[pos_[i]];
  316. if (val == q) {
  317. return true;
  318. }
  319. bfs_pos <<= 1;
  320. if (val < q) {
  321. bfs_pos |= 1;
  322. }
  323. if (i == lg_) {
  324. return false;
  325. }
  326. d++;
  327. int log_len = tt_[d];
  328. int top = log_len >> 1;
  329. int bottom = log_len - top;
  330. top = (1 << top) - 1;
  331. auto bottom_pos = (bfs_pos & top);
  332. pos_[d] = pos_[d_[d]] + top + (bottom_pos << bottom) - bottom_pos;
  333. }
  334. exit(1);
  335. }
  336.  
  337. virtual ~VanEmdeBoasSolver() {}
  338.  
  339. private:
  340. vector<uint8_t> tt_;
  341. vector<uint8_t> d_;
  342. vector<int> pos_;
  343. int lg_;
  344. vector<uint64_t> layout_;
  345. vector<uint64_t> tmp_;
  346. };
  347.  
  348. void GetResultsForOneSolver(const vector<uint64_t> &queries, ostream *outputs, BinsearchSolver *solver) {
  349. for (auto q : queries) {
  350. solver->Process(q);
  351. }
  352. solver->OutputResults(*outputs);
  353. }
  354.  
  355. void GetResultsForAllSolversVector(const vector<uint64_t> &arr, const vector<uint64_t> &queries, int b,
  356. map<string, ostream *> outputs) {
  357. {
  358. DefaultBinsearchSolver dbs(arr, "bs");
  359. GetResultsForOneSolver(queries, outputs["bs"], &dbs);
  360. }
  361. {
  362. SqrtBinsearchSolver sbs(arr, "sqrt");
  363. GetResultsForOneSolver(queries, outputs["sqrt"], &sbs);
  364. }
  365. {
  366. BTreeBinsearchSolver bbs(arr, "btree", b);
  367. GetResultsForOneSolver(queries, outputs["btree"], &bbs);
  368. }
  369. {
  370. VanEmdeBoasSolver veb(arr, "veb");
  371. GetResultsForOneSolver(queries, outputs["veb"], &veb);
  372. }
  373.  
  374. }
  375.  
  376. void GetResultsForAllSolversIO(istream &input, int b, map<string, ostream *> outputs) {
  377. int n;
  378. input >> n;
  379. vector<uint64_t> arr(n);
  380. for (auto &el : arr) {
  381. input >> el;
  382. }
  383. int m;
  384. input >> m;
  385. vector<uint64_t> queries(m);
  386. for (auto &q : queries) {
  387. input >> q;
  388. }
  389. GetResultsForAllSolversVector(arr, queries, b, outputs);
  390. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement