fork download
  1. // find_S.cpp
  2. // In ra một giá trị S sao cho tồn tại hai subset khác nhau (rời nhau sau khi lấy hiệu)
  3. // có cùng tổng = S. Nếu không tìm thấy in IMPOSSIBLE.
  4. // n <= 40, a[i] > 0
  5.  
  6. #include <bits/stdc++.h>
  7. using namespace std;
  8. using ll = long long;
  9. using ull = unsigned long long;
  10.  
  11. int main() {
  12. ios::sync_with_stdio(false);
  13. cin.tie(nullptr);
  14. int n;
  15. if (!(cin >> n)) return 0;
  16. vector<ll> a(n);
  17. for (int i = 0; i < n; ++i) cin >> a[i];
  18.  
  19. int left = n / 2;
  20. int right = n - left;
  21. int L = 1 << left;
  22. int R = 1 << right;
  23.  
  24. unordered_map<ll, ull> map_left; // sum -> mask (bits in low positions for left)
  25. map_left.reserve(max(16, L*2));
  26.  
  27. // enumerate left; detect duplicate sums inside left
  28. vector<ll> sum_left(L, 0);
  29. for (int mask = 0; mask < L; ++mask) {
  30. if (mask == 0) {
  31. sum_left[mask] = 0;
  32. } else {
  33. int lsb = mask & -mask;
  34. int prev = mask ^ lsb;
  35. int idx = __builtin_ctz((unsigned)lsb);
  36. sum_left[mask] = sum_left[prev] + a[idx];
  37. }
  38. ll s = sum_left[mask];
  39. auto it = map_left.find(s);
  40. if (it != map_left.end()) {
  41. ull other = it->second;
  42. if (other != (ull)mask) {
  43. cout << s << '\n';
  44. return 0;
  45. }
  46. } else {
  47. map_left[s] = (ull)mask;
  48. }
  49. }
  50.  
  51. // enumerate right; detect duplicate inside right and cross with left
  52. unordered_map<ll, ull> map_right;
  53. map_right.reserve(max(16, R*2));
  54. vector<ll> sum_right(R, 0);
  55. for (int mask = 0; mask < R; ++mask) {
  56. if (mask == 0) {
  57. sum_right[mask] = 0;
  58. } else {
  59. int lsb = mask & -mask;
  60. int prev = mask ^ lsb;
  61. int idx = __builtin_ctz((unsigned)lsb); // index inside right
  62. sum_right[mask] = sum_right[prev] + a[left + idx];
  63. }
  64. ll s = sum_right[mask];
  65. ull fullmask = ((ull)mask) << left; // mask in full n-bit space
  66. // duplicate in right
  67. auto itR = map_right.find(s);
  68. if (itR != map_right.end()) {
  69. ull other = itR->second;
  70. if (other != fullmask) {
  71. cout << s << '\n';
  72. return 0;
  73. }
  74. } else {
  75. map_right[s] = fullmask;
  76. }
  77. // cross left vs right
  78. auto itL = map_left.find(s);
  79. if (itL != map_left.end()) {
  80. ull leftmask = itL->second;
  81. // leftmask and fullmask are in disjoint bit ranges -> valid
  82. cout << s << '\n';
  83. return 0;
  84. }
  85. }
  86.  
  87. // As a fallback (practically shouldn't happen under given constraints), try
  88. // enumerating all subsets if n small
  89. if (n <= 22) {
  90. unordered_map<ll, ull> full;
  91. ull tot = 1ULL << n;
  92. for (ull mask = 0; mask < tot; ++mask) {
  93. ll s = 0;
  94. ull tmp = mask;
  95. while (tmp) {
  96. int b = __builtin_ctzll(tmp);
  97. s += a[b];
  98. tmp &= tmp - 1ULL;
  99. }
  100. auto it = full.find(s);
  101. if (it != full.end()) {
  102. ull other = it->second;
  103. if (other != mask) {
  104. cout << s << '\n';
  105. return 0;
  106. }
  107. } else full[s] = mask;
  108. }
  109. }
  110.  
  111. cout << "IMPOSSIBLE\n";
  112. return 0;
  113. }
  114.  
Success #stdin #stdout 0.01s 5320KB
stdin
4
1 2 4 7
stdout
0