#include <iostream> #include <vector> #include <algorithm> //#include <fstream> using namespace std; class Item { public: long long m; long long sum; Item(long long int m, long long int sum) : m(m), sum(sum) {} bool operator<(const Item &rhs) const { if (m < rhs.m) return true; if (rhs.m < m) return false; return sum > rhs.sum; } }; int getBits(long long int m); long long int getNextWithLowerBitCount(long long int i); long long int getNextWithHigherBitCount(long long int m); const int BITS = 63; int main() { ios_base::sync_with_stdio(0); cin.tie(0); // std::ifstream in("0.in"); // std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf // std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt! // while (std::cin.peek() != std::char_traits<char>::eof()) { int n; long long m; cin >> n; cin >> m; long long a; vector<Item> items; vector<Item> prev; prev.push_back(Item(- 1, 0)); for (int i = 0; i < n; i++) { cin >> a; for (auto t = prev.begin(); t != prev.end(); ++t) { long long currentM = t->m + 1; long long currentSum = t->sum; int currentBits = getBits(currentM); items.push_back(Item(currentM, currentSum + (currentBits * a))); if (a < 0) { long long nextWithLowerBitCount = currentM; for (int bits = currentBits - 1; bits >= 0; bits--) { nextWithLowerBitCount = getNextWithLowerBitCount(nextWithLowerBitCount); int currentBits2 = getBits(nextWithLowerBitCount); if (nextWithLowerBitCount <= m - n + i + 1) { items.push_back(Item(nextWithLowerBitCount, currentSum + (currentBits2 * a))); } else { break; } } } else { long long nextWithHigherBitCount = currentM; for (int bits = currentBits + 1; bits < BITS; bits++) { nextWithHigherBitCount = getNextWithHigherBitCount(nextWithHigherBitCount); int currentBits2 = getBits(nextWithHigherBitCount); if (nextWithHigherBitCount <= m - n + i + 1) { items.push_back(Item(nextWithHigherBitCount, currentSum + (currentBits2 * a))); } else { break; } } } } sort(items.begin(), items.end()); prev.clear(); long long max = std::numeric_limits<long long>::min(); for (auto t = items.begin(); t != items.end(); ++t) { if (t->sum > max) { prev.push_back(Item(t->m, t->sum)); max = t->sum; } } items.clear(); } long long max = std::numeric_limits<long long>::min(); for (auto t = prev.begin(); t != prev.end(); ++t) { if (t->sum > max) { max = t->sum; } } std::cout << max << std::endl; // } return 0; } long long int getNextWithHigherBitCount(long long m) { long long x = 1; for (int i = 0; i < BITS; i++) { if ((m & x) == 0) { return m | x; } x <<= 1; } return 0; } long long int getNextWithLowerBitCount(long long m) { long long x = 1; int ones = 0; for (int i = 0; i < 63; i++) { if ((m & x) > 0) { ones++; m &= ~x; } else { if (ones > 1) { return m | x; } } x <<= 1; } return std::numeric_limits<long long>::max(); } int getBits(long long int m) { return __builtin_popcountll(m); } //int getBits(long long int m) { // int count = 0; // while (m) { // count += m & 1; // m >>= 1; // } // return count; //}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | #include <iostream> #include <vector> #include <algorithm> //#include <fstream> using namespace std; class Item { public: long long m; long long sum; Item(long long int m, long long int sum) : m(m), sum(sum) {} bool operator<(const Item &rhs) const { if (m < rhs.m) return true; if (rhs.m < m) return false; return sum > rhs.sum; } }; int getBits(long long int m); long long int getNextWithLowerBitCount(long long int i); long long int getNextWithHigherBitCount(long long int m); const int BITS = 63; int main() { ios_base::sync_with_stdio(0); cin.tie(0); // std::ifstream in("0.in"); // std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf // std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt! // while (std::cin.peek() != std::char_traits<char>::eof()) { int n; long long m; cin >> n; cin >> m; long long a; vector<Item> items; vector<Item> prev; prev.push_back(Item(- 1, 0)); for (int i = 0; i < n; i++) { cin >> a; for (auto t = prev.begin(); t != prev.end(); ++t) { long long currentM = t->m + 1; long long currentSum = t->sum; int currentBits = getBits(currentM); items.push_back(Item(currentM, currentSum + (currentBits * a))); if (a < 0) { long long nextWithLowerBitCount = currentM; for (int bits = currentBits - 1; bits >= 0; bits--) { nextWithLowerBitCount = getNextWithLowerBitCount(nextWithLowerBitCount); int currentBits2 = getBits(nextWithLowerBitCount); if (nextWithLowerBitCount <= m - n + i + 1) { items.push_back(Item(nextWithLowerBitCount, currentSum + (currentBits2 * a))); } else { break; } } } else { long long nextWithHigherBitCount = currentM; for (int bits = currentBits + 1; bits < BITS; bits++) { nextWithHigherBitCount = getNextWithHigherBitCount(nextWithHigherBitCount); int currentBits2 = getBits(nextWithHigherBitCount); if (nextWithHigherBitCount <= m - n + i + 1) { items.push_back(Item(nextWithHigherBitCount, currentSum + (currentBits2 * a))); } else { break; } } } } sort(items.begin(), items.end()); prev.clear(); long long max = std::numeric_limits<long long>::min(); for (auto t = items.begin(); t != items.end(); ++t) { if (t->sum > max) { prev.push_back(Item(t->m, t->sum)); max = t->sum; } } items.clear(); } long long max = std::numeric_limits<long long>::min(); for (auto t = prev.begin(); t != prev.end(); ++t) { if (t->sum > max) { max = t->sum; } } std::cout << max << std::endl; // } return 0; } long long int getNextWithHigherBitCount(long long m) { long long x = 1; for (int i = 0; i < BITS; i++) { if ((m & x) == 0) { return m | x; } x <<= 1; } return 0; } long long int getNextWithLowerBitCount(long long m) { long long x = 1; int ones = 0; for (int i = 0; i < 63; i++) { if ((m & x) > 0) { ones++; m &= ~x; } else { if (ones > 1) { return m | x; } } x <<= 1; } return std::numeric_limits<long long>::max(); } int getBits(long long int m) { return __builtin_popcountll(m); } //int getBits(long long int m) { // int count = 0; // while (m) { // count += m & 1; // m >>= 1; // } // return count; //} |