Advertisement
Guest User

Untitled

a guest
Feb 19th, 2020
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.54 KB | None | 0 0
  1. #include "find_subsets.h"
  2. #include <stdexcept>
  3. #include <vector>
  4. #include <unordered_map>
  5. #include <thread>
  6. #include <iostream>
  7. #include <atomic>
  8.  
  9. int64_t tpow[16] = {1,    3,     9,     27,     81,     243,     729,     2187,
  10.                     6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907};
  11.  
  12. void Fill(const std::vector<int64_t>& data, std::unordered_map<int64_t, int64_t>* mp) {
  13.     int64_t mask, sum, mod;
  14.     for (int64_t i = 1; i < tpow[data.size()]; i++) {
  15.         mask = i;
  16.         sum = 0;
  17.         for (int j = 0; mask; j++) {
  18.             mod = mask % 3;
  19.             if (mod == 1) {
  20.                 sum += data[j];
  21.             } else if (mod == 2) {
  22.                 sum -= data[j];
  23.             }
  24.             mask /= 3;
  25.         }
  26.         (*mp)[sum] = i;
  27.     }
  28. }
  29.  
  30. Subsets GetSubsets(int64_t mask) {
  31.     Subsets res;
  32.     int j = 0;
  33.     while (mask) {
  34.         int mod = mask % 3;
  35.         if (mod == 1) {
  36.             res.first_indices.push_back(j);
  37.         } else if (mod == 2) {
  38.             res.second_indices.push_back(j);
  39.         }
  40.         mask /= 3;
  41.         j++;
  42.     }
  43.     return res;
  44. }
  45.  
  46. Subsets FindEqualSumSubsets(const std::vector<int64_t>& data) {
  47.     int sz = data.size();
  48.     std::vector<int64_t> data1;
  49.     std::vector<int64_t> data2;
  50.     for (int i = 0; i < sz / 2; i++) {
  51.         data1.push_back(data[i]);
  52.     }
  53.     for (int i = sz / 2; i < sz; i++) {
  54.         data2.push_back(data[i]);
  55.     }
  56.     std::unordered_map<int64_t, int64_t> first_half;
  57.     std::unordered_map<int64_t, int64_t> second_half;
  58.  
  59.     std::thread th1(Fill, data1, &first_half);
  60.     std::thread th2(Fill, data2, &second_half);
  61.     th1.join();
  62.     th2.join();
  63.  
  64.     for (auto& [key, val] : first_half) {
  65.         if (second_half.count(-key)) {
  66.             Subsets buf = GetSubsets(second_half[-key] * tpow[sz / 2] + val);
  67.             if (!buf.first_indices.empty() && !buf.second_indices.empty()) {
  68.                 buf.exists = 1;
  69.                 return buf;
  70.             }
  71.         }
  72.     }
  73.  
  74.     if (first_half.count(0)) {
  75.         auto res = GetSubsets(first_half[0]);
  76.         if (!res.first_indices.empty() && !res.second_indices.empty()) {
  77.             res.exists = true;
  78.             return res;
  79.         }
  80.     }
  81.  
  82.     if (second_half.count(0)) {
  83.         Subsets res = GetSubsets(second_half[0] * tpow[sz / 2]);
  84.         if (!res.first_indices.empty() && !res.second_indices.empty()) {
  85.             res.exists = true;
  86.             return res;
  87.         }
  88.     }
  89.  
  90.     Subsets res;
  91.     res.exists = 0;
  92.     return res;
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement