Submission #1169110

#TimeUsernameProblemLanguageResultExecution timeMemory
1169110SmuggingSpunCarnival Tickets (IOI20_tickets)C++20
100 / 100
617 ms100712 KiB
#include "tickets.h"
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool minimize(T& a, T b){
    if(a > b){
        a = b;
        return true;
    }
    return false;
}
template<class T>bool maximize(T& a, T b){
    if(a < b){
        a = b;
        return true;
    }
    return false;
}
const int lim = 1505;
int n, m, k, a[lim][lim];
namespace sub1{
    ll solve(){
        vector<int>A;
        vector<vector<int>>s(n, vector<int>(m));
        for(int i = 0; i < n; i++){
            A.emplace_back(a[i][0]);
            s[i][0] = 0;
        }
        allocate_tickets(s);
        sort(A.begin(), A.end());
        int median = A[n >> 1];
        ll ans = 0;
        for(int& x : A){
            ans += abs(x - median);
        }
        return ans;
    }
}
namespace sub2{
    ll solve(){
        vector<vector<int>>p(n, vector<int>(2));
        for(int i = 0; i < n; i++){
            if((p[i][0] = min_element(a[i], a[i] + m) - a[i]) == (p[i][1] = max_element(a[i], a[i] + m) - a[i])){
                p[i][0] = 0;
                p[i][1] = 1;
            }
        }
        vector<pair<int, bool>>value;
        for(int i = 0; i < n; i++){
            value.emplace_back(i, false);
            value.emplace_back(i, true);
        }
        sort(value.begin(), value.end(), [&] (auto i, auto j){
            return a[i.first][p[i.first][i.second]] < a[j.first][p[j.first][j.second]];
        });
        vector<pair<int, int>>best;
        ll ans = 0;
        for(int i = 0; i < (n << 1); i++){
            ll sum = -a[value[i].first][p[value[i].first][value[i].second]];
            vector<int>cnt(n, 0);
            vector<bool>use(n, false);
            use[value[i].first] = true;
            vector<pair<int, int>>left, right;
            for(int j = i - 1; j > -1; j--){
                if(++cnt[value[j].first] == 2){
                    left.emplace_back(value[j].first, p[value[j].first][value[j].second]);
                    sum -= a[value[j].first][p[value[j].first][value[j].second]];
                    use[value[j].first] = true;
                }
            }
            fill(cnt.begin(), cnt.end(), 0);
            for(int j = i + 1; j < (n << 1); j++){
                if(++cnt[value[j].first] == 2){
                    right.emplace_back(value[j].first, p[value[j].first][value[j].second]);
                    sum += a[value[j].first][p[value[j].first][value[j].second]];
                    use[value[j].first] = true;
                }
            }
            if(left.size() < (n >> 1) && right.size() <= (n >> 1)){
                vector<int>index, lv(n), rv(n), lp(n), rp(n);
                for(int j = 0; j < i; j++){
                    if(!use[value[j].first]){
                        index.emplace_back(value[j].first);
                        lv[value[j].first] = a[value[j].first][lp[value[j].first] = p[value[j].first][value[j].second]];
                    }
                }
                for(int j = i + 1; j < (n << 1); j++){
                    if(!use[value[j].first]){
                        rv[value[j].first] = a[value[j].first][rp[value[j].first] = p[value[j].first][value[j].second]];
                    }
                }
                int median = a[value[i].first][p[value[i].first][value[i].second]];
                sort(index.begin(), index.end(), [&] (int x, int y){
                    return abs(lv[x] - median) - abs(rv[x] - median) > abs(lv[y] - median) - abs(rv[y] - median);
                });
                for(int j = (n >> 1) - int(left.size()) - 1; j > 0; ){
                    sum -= lv[index[--j]];
                    left.emplace_back(index[j], lp[index[j]]);
                }
                for(int j = (n >> 1) - int(right.size()); j > 0; j--){
                    int t = int(index.size()) - j;
                    sum += rv[index[t]];
                    right.emplace_back(index[t], rp[index[t]]);
                }
                if(maximize(ans, sum)){
                    left.emplace_back(value[i].first, p[value[i].first][value[i].second]);
                    swap(best, left);
                    for(auto& it : right){
                        best.emplace_back(it);
                    }
                }
            }
        }
        vector<vector<int>>s(n, vector<int>(m, -1));
        for(auto& [i, j] : best){
            s[i][j] = 0;
        }
        allocate_tickets(s);
        return ans;
    }
}
namespace sub4{
    ll solve(){
        vector<pair<int, int>>p;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                p.emplace_back(i, j);
            }
        }
        sort(p.begin(), p.end(), [&] (auto i, auto j){
            return a[i.first][i.second] > a[j.first][j.second];
        });
        vector<vector<bool>>big(n, vector<bool>(m, false));
        for(int i = (n * m) >> 1; i > 0; ){
            i--;
            big[p[i].first][p[i].second] = true;
        }
        vector<vector<int>>ans(n, vector<int>(m));
        ll sum = 0;
        deque<pair<int, int>>dq;
        for(int i = 0; i < m; i++){
            dq.emplace_back(n >> 1, i);
        }
        for(int i = 0; i < n; i++){
            for(int t = 0; t < m; t++){
                if(big[i][t]){
                    sum += a[i][t];
                    auto [u, v] = dq.front();
                    dq.pop_front();
                    if(u > 0){
                        dq.emplace_back(u - 1, v);
                    }
                    ans[i][t] = v;
                }
            }
        }
        for(int i = 0; i < n; i++){
            vector<bool>use(m, false);            
            for(int t = 0; t < m; t++){
                if(big[i][t]){
                    use[ans[i][t]] = true;
                }
            }
            vector<int>I;
            for(int t = 0; t < m; t++){
                if(!use[t]){
                    I.emplace_back(t);
                }
            }
            for(int t = 0; t < m; t++){
                if(!big[i][t]){
                    sum -= a[i][t];
                    ans[i][t] = I.back();
                    I.pop_back();
                }
            }
        }
        allocate_tickets(ans);
        return sum;
    }
}
namespace sub3567{
    ll solve(){
        ll sum = 0;
        vector<tuple<int, int, int, int>>greed;
        vector<vector<int>>ans(n, vector<int>(m, -1));
        for(int i = 0; i < n; i++){
            vector<int>p(m);
            iota(p.begin(), p.end(), 0);
            sort(p.begin(), p.end(), [&] (int x, int y){
                return a[i][x] < a[i][y];
            });
            for(int j = 0; j < k; j++){
                sum -= a[i][p[j]];
                ans[i][p[j]] = -2;
                greed.emplace_back(i, p[j], p[m - k + j], j);
            }
        }
        sort(greed.begin(), greed.end(), [&] (auto i, auto j){
            auto& [xi, yi1, yi2, pi] = i;
            auto& [xj, yj1, yj2, pj] = j;
            int sum_i = a[xi][yi1] + a[xi][yi2], sum_j = a[xj][yj1] + a[xj][yj2];
            return sum_i > sum_j || (sum_i == sum_j && pi > pj);
        });
        for(int i = 0; i < ((n * k) >> 1); i++){
            auto [x, y1, y2, foo] = greed[i];
            ans[x][y1] = -1;
            ans[x][y2] = -3;
            sum += a[x][y1] + a[x][y2];
        }
        deque<pair<int, int>>dq;
        for(int i = 0; i < k; i++){
            dq.emplace_back(n >> 1, i);
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(ans[i][j] == -3){
                    auto [u, v] = dq.front();
                    dq.pop_front();
                    if(u > 0){
                        dq.emplace_back(u - 1, v);
                    }
                    ans[i][j] = v;
                }
            }
        }
        for(int i = 0; i < n; i++){
            vector<bool>use(k, false);            
            for(int j = 0; j < m; j++){
                if(ans[i][j] > -1){
                    use[ans[i][j]] = true;
                }
            }
            vector<int>I;
            for(int j = 0; j < k; j++){
                if(!use[j]){
                    I.emplace_back(j);
                }
            }
            for(int j = 0; j < m; j++){
                if(ans[i][j] == -2){
                    ans[i][j] = I.back();
                    I.pop_back();
                }
            }
        }
        allocate_tickets(ans);
        return sum;
    }
}
ll find_maximum(int _k, vector<vector<int>>_x){
    n = _x.size();
    m = _x[0].size();
    k = _k;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            a[i][j] = _x[i][j];
        }
    }
    if(m == 1){
        return sub1::solve();
    }
    if(k == 1){
        return sub2::solve();
    }
    if(k == m){
        return sub4::solve();
    }
    return sub3567::solve();
}
#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...