Submission #1347314

#TimeUsernameProblemLanguageResultExecution timeMemory
1347314MisterReaperCouncil (JOI23_council)C++20
100 / 100
1833 ms42428 KiB
#include <bits/stdc++.h>

using i64 = long long;

#ifdef DEBUG
    #include "debug.h"
#else
    #define debug(...) void(23)
#endif

constexpr int inf = int(1E9) + 5;
constexpr int max_N = int(3E5) + 5;
constexpr int max_M = 20;

int N;
int M;
int A[max_N][max_M];
int cnt[max_M];
int msk[max_N];
std::pair<int, int> f[1 << max_M / 2][1 << max_M / 2];
std::pair<int, int> g[1 << max_M / 2][1 << max_M / 2];

void clear(std::vector<std::pair<int, int>>& vec) {
    while (vec[1].second == vec[0].second) {
        vec.erase(vec.begin() + 1);
    }
    vec.resize(2);
}

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    for (int i = 0; i < (1 << max_M / 2); ++i) {
        for (int j = 0; j < (1 << max_M / 2); ++j) {
            f[i][j] = {-inf, -1};
            g[i][j] = {-inf, -1};
        }
    }

    std::cin >> N >> M;

    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            std::cin >> A[i][j];
            msk[i] |= !A[i][j] << j;
        }
    }

    for (int i = 0; i < M; ++i) {
        cnt[i] -= N / 2;
    }
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            cnt[j] += A[i][j];
        }
    }

    for (int i = 0; i < (1 << M / 2); ++i) {
        std::vector<std::array<int, 2>> h(1 << M - M / 2, {-1, -1});
        std::vector<std::pair<int, int>> aux_f(1 << M - M / 2, {-inf, -1});
        std::vector<std::pair<int, int>> aux_g(1 << M - M / 2, {-inf, -2});
        for (int j = 0; j < N; ++j) {
            if ((msk[j] & i) == i) {
                if (h[msk[j] >> M / 2][0] == -1) {
                    h[msk[j] >> M / 2][0] = j;
                } else if (h[msk[j] >> M / 2][1] == -1) {
                    h[msk[j] >> M / 2][1] = j;
                }
            }
        }
        for (int j = 0; j < (1 << M - M / 2); ++j) {
            for (auto idx : h[j]) {
                if (idx == -1) {
                    continue;
                }
                for (int k = j; ; k = (k - 1) & j) {
                    if (aux_f[k].first <= __builtin_popcount(k)) {
                        aux_g[k] = aux_f[k];
                        aux_f[k] = {__builtin_popcount(k), idx};
                    } else if (aux_g[k].first <= __builtin_popcount(k)) {
                        aux_g[k] = {__builtin_popcount(k), idx};
                    }
                    if (k == 0) {
                        break;
                    }
                }
            }
        }
        for (int j = 0; j < (1 << M - M / 2); ++j) {
            std::vector<std::pair<int, int>> vec;
            vec.emplace_back(-inf, -1);
            vec.emplace_back(-inf, -2);
            for (int k = j; ; k = (k - 1) & j) {
                vec.emplace_back(aux_f[k]);
                vec.emplace_back(aux_g[k]);
                std::sort(vec.begin(), vec.end(), std::greater());
                clear(vec);
                if (k == 0) {
                    break;
                }
            }
            f[i][j] = vec[0];
            g[i][j] = vec[1];
        }
        #ifdef DEBUG
            if (i == 1) {
                for (int j = 0; j < (1 << M - M / 2); ++j) {
                    debug(aux_f[j], aux_g[j]);
                }
                for (int j = 0; j < (1 << M - M / 2); ++j) {
                    debug(f[i][j], g[i][j]);
                }
            }
        #endif
    }

    for (int i = 0; i < N; ++i) {
        // debug(i);
        for (int j = 0; j < M; ++j) {
            cnt[j] -= A[i][j];
        }
        int res = 0, ss = 0;
        for (int j = 0; j < M; ++j) {
            if (cnt[j] > 0) {
                res += 1;
            } else if (cnt[j] == 0) {
                ss |= 1 << j;
            }
        }
        
        int mx = 0;
        for (int j = 0; j < (1 << M / 2); ++j) {
            if ((ss & j) != j) {
                continue;
            }
            debug(j, f[j][ss >> M / 2], g[j][ss >> M / 2]);
            mx = std::max(mx, __builtin_popcount(j) + (f[j][ss >> M / 2].second == i ? g[j][ss >> M / 2].first : f[j][ss >> M / 2].first));
        }
        debug(i, ss, res, mx);
        std::cout << res + mx << '\n';
        for (int j = 0; j < M; ++j) {
            cnt[j] += A[i][j];
        }
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...