Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize("O3")
- #include <bits/stdc++.h>
- using namespace std;
- typedef long double ld;
- typedef long long ll;
- int n;
- const int maxN = 2 * (int)1e5 + 100;
- const int LIM = 62;
- ll a[maxN];
- ll dp[LIM + 10][maxN];
- const ll one = 1;
- const ll INF = (one << LIM);
- int bit(int x) {
- int bt = 0;
- for (int i = 0; i <= 20; i++) {
- if (x & (1 << i)) bt++;
- }
- return bt;
- }
- int solve_stupid() {
- int ans = (int)1e9;
- for (int i = 0; i <= 1000000; i++) {
- int cur = 0;
- for (int j = 1; j <= n; j++) {
- cur += bit(a[j] + i);
- }
- ans = min(ans, cur);
- }
- return ans;
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- //freopen("input.txt", "r", stdin);
- srand(time(0));
- cin >> n;
- //n = rand() % 1000 + 10;
- ll mx = 0;
- for (int i = 1; i <= n; i++) {
- cin >> a[i];
- //a[i] = rand() % 1242 + 10;
- mx = max(mx, a[i]);
- }
- for (int i = 1; i <= n; i++) {
- a[i] = mx - a[i];
- }
- for (int i = 0; i <= LIM + 4; i++) {
- for (int j = 0; j <= n; j++) {
- dp[i][j] = INF;
- }
- }
- dp[0][0] = 0;
- vector < int > f;
- for (int i = 1; i <= n; i++) f.push_back(i);
- for (int bit = 0; bit <= LIM; bit++) {
- if (bit != 0) {
- vector<int> nf;
- for (int v : f) {
- if (!(a[v] & (one << (bit - 1)))) nf.push_back(v);
- }
- for (int v : f) {
- if (a[v] & (one << (bit - 1))) nf.push_back(v);
- }
- f = nf;
- }
- vector < int > prefZeroes(n + 1);
- vector < int > prefOnes(n + 1);
- prefZeroes[0] = prefOnes[0] = 0;
- for (int i = 1; i <= n; i++) {
- prefOnes[i] = prefOnes[i - 1];
- prefZeroes[i] = prefZeroes[i - 1];
- if (a[f[i - 1]] & (one << bit)) prefOnes[i]++;
- else prefZeroes[i]++;
- }
- int total_zeroes = prefZeroes[n];
- int total_ones = prefOnes[n];
- assert(total_ones + total_zeroes == n);
- for (int suf_take = 0; suf_take <= n; suf_take++) {
- for (int bt = 0; bt < 2; bt++) {
- if (dp[bit][suf_take] == INF) continue;
- if (bt == 0) {
- int numOnes = (total_zeroes - prefZeroes[n - suf_take]) + prefOnes[n - suf_take];
- int carry_ones = (total_ones - prefOnes[n - suf_take]);
- dp[bit + 1][carry_ones] = min(dp[bit + 1][carry_ones], dp[bit][suf_take] + numOnes);
- }
- else {
- int numOnes = (total_ones - prefOnes[n - suf_take]) + prefZeroes[n - suf_take];
- int carry_ones = n - prefZeroes[n - suf_take];
- dp[bit + 1][carry_ones] = min(dp[bit + 1][carry_ones], dp[bit][suf_take] + numOnes);
- }
- }
- }
- }
- ll ans = dp[LIM + 1][0];
- //assert(ans == solve_stupid());
- cout << ans;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement