Submission #576564

#TimeUsernameProblemLanguageResultExecution timeMemory
576564MadokaMagicaFan카니발 티켓 (IOI20_tickets)C++14
41 / 100
982 ms132192 KiB
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using vi = vector<int>;
using vll = vector<ll>;
using pi = pair<int,int>;

const ll inf = 1e10;

#define all(v)          v.begin(),v.end()
#define sort(v)         sort(all(v))
#define endl            '\n'
#define forn(i,n)       for(int i = 0; i < n; ++i)
#define forbe(i,b,e)    for(int i = b; i < e; ++i)
#define forr(i,n)       for(int i = n-1; i >= 0; --i)
#define sz(v)           ((int)v.size())
#define pb              push_back
#define f               first
#define s               second

const int N = 1505;
const int M = 1505;

void allocate_tickets(vector<vi>s);

ll subtask1(int k, vector<vi> &x) {
    int n = sz(x);
    int m = sz(x[0]);
    vector<vi> s(n);
    forn(i,n) s[i].assign(m,0);

    vi ans;

    forn(i,n) {
        ans.pb(x[i][0]);
    }

    sort(ans);
    
    ll rans = 0;

    forn(i,n) {
        if (i < (n>>1))
            rans -= ans[i];
        else
            rans += ans[i];
    }

    forn(i,n) {
        s[i][0] = 0;
    }

    allocate_tickets(s);

    return rans;
}

ll subtask4(int k, vector<vi> &x) {
    int n = sz(x);
    int m = sz(x[0]);
    vector<vi> s(n);
    forn(i,n) s[i].assign(m,0);
    vector<pair<ll,int>> vals;
    vector<vector<pair<ll,int>>> sval(n);

    int topp[N];
    int botp[N];

    forn(i,n) {
        topp[i] = m-1;
        botp[i] = 0;
        forn(j,m) {
            sval[i].pb({x[i][j], j});
            vals.pb({x[i][j],i * m + j});
        }
        sort(sval[i]);
    }

    ll ans = 0;
    sort(vals);
    bitset<N*M> c;
    bitset<N*M> mid;

    int midval = vals[((n*m)>>1)].f;
    forn(i,n*m) {
        ans -= (ll)vals[i].f;
        if (vals[i].f == midval)
            mid[vals[i].s] = 1;
        if (i < ((n*m)>>1)) continue;
        c[vals[i].s] = 1;
        ans += (ll)vals[i].f;
        ans += (ll)vals[i].f;
    }

//    forn(i,m) {
//        forn(j, n) {
//            cout << c[ j*m + sval[j][m-i-1].s ] << ' ';
//        }
//        cout << endl;
//    }

    bitset<N> up;
    int cnt;
    forn(j, k) {
        forn(i,n) up[i] = 0;
        cnt = 0;
        forn(i,n) {
            if (cnt == (n>>1))
                break;
            if (c[ i*m + sval[i][topp[i]].s ] == 0 || 
                c[ i*m + sval[i][botp[i]].s ] == 0) continue;
            ++cnt;
//            cout << "Sel " << i << endl;
            up[i]=1;
        }

        forn(i,n) {
            if (cnt == (n>>1))
                break;
            if (up[i]) continue;
            if (c[ i*m + sval[i][topp[i]].s ] == 0 || 
                mid[ i*m + sval[i][botp[i]].s ] == 0) continue;
            ++cnt;
            up[i]=1;
        }

        forn(i,n) {
            if (cnt == (n>>1))
                break;
            if (up[i]) continue;
            if (c[ i*m + sval[i][topp[i]].s ] == 0) continue;
            ++cnt;
            up[i]=1;
        }

        forn(i,n) {
            if (cnt == (n>>1))
                break;
            if (up[i]) continue;
            if (mid[ i*m + sval[i][topp[i]].s ] == 0 || 
                c[ i*m + sval[i][botp[i]].s ] == 0) continue;
            ++cnt;
            up[i]=1;
        }

        forn(i,n) {
            if (cnt == (n>>1))
                break;
            if (up[i]) continue;
            if (mid[ i*m + sval[i][topp[i]].s ] == 0 || 
                mid[ i*m + sval[i][botp[i]].s ] == 0) continue;
            ++cnt;
            up[i]=1;
        }

        forn(i,n) {
            if (cnt == (n>>1))
                break;
            if (up[i]) continue;
            if (mid[ i*m + sval[i][topp[i]].s ] == 0) continue;
            ++cnt;
            up[i]=1;
        }

//        cout << cnt << endl;
//        forn(i,n) {
//            cout << topp[i] << ' ';
//        }
//        cout << endl;
//        forn(i,n) {
//            cout << botp[i] << ' ';
//        }
//        cout << endl;
        assert(cnt == (n>>1));

        forn(i,n) {
            if (up[i]) {
                s[i][ sval[i][topp[i]].s ] = j;
                --topp[i];
            } else {
                s[i][ sval[i][botp[i]].s ] = j;
                ++botp[i];
            }
        }
    }

    allocate_tickets(s);

    return ans;
}

ll subtask2(int k, vector<vi> &x) {
    int n = sz(x);
    int m = sz(x[0]);
    vector<vi> s(n);
    forn(i,n) s[i].assign(m,-1);
    vi minval(n);
    vi maxval(n);

    bitset<N> c;

    vector<pair<ll,int>> vs;
    forn(i,n) {
        ll mv = 1e9+2;
        ll mx = -1;
        forn(j, m) {
            if (mv > x[i][j]) {
                minval[i] = j;
                mv = x[i][j];
            }
            if (mx < x[i][j]) {
                maxval[i] = j;
                mx = x[i][j];
            }
        }
        vs.pb({mx+mv,i});
    }

    sort(vs);

    ll ans = 0;
    forn(u,n) {
        int i = vs[u].s;
        if (u < (n>>1)) {
            ans -= (ll)x[i][minval[i]];
            s[i][minval[i]] = 0;
        } else {
            ans += (ll)x[i][maxval[i]];
            s[i][maxval[i]] = 0;
        }
    }
    allocate_tickets(s);

    return ans;
}

using pl = pair<ll,int>;

ll subtaskidk(int k, vector<vi> &x) {
    int n = sz(x);
    int m = sz(x[0]);
    vector<vi> s(n);
    vector<pair<ll,int>> vals;
    forn(i,n) s[i].assign(m,-1);
    vector<vector<pair<ll,int>>> sval(n);

    int topp[N];
    int botp[N];

    forn(i,n) {
        forn(j,m) {
            sval[i].pb({x[i][j], j});
            vals.pb({x[i][j],i * m + j});
        }
        sort(sval[i]);
    }

    sort(vals);
    bitset<N*M> c;
    bitset<N*M> z;

    forn(i,n) {
        if (i < (n>>1)) {
            topp[i] = m-1;
            botp[i] = k;
        } else {
            topp[i] = m-1-k;
            botp[i] = 0;
        }
    }

//    priority_queue<pl> q1;
//    priority_queue<pl, vector<pl>, greater<pl>> q2;
//    
//    forn(i,n) {
//        if (botp[i])    q1.push({sval[i][ botp[i]-1 ].f + sval[i][ topp[i] ].f, i});
//        else            q1.push({-inf,i});
//
//        if (topp[i]<m-1)    q2.push({sval[i][ botp[i] ].f + sval[i][ topp[i]+1 ].f, i});
//        else                q2.push({inf,i});
//    }
//    while (sz(q1)) {
//        auto u1 = q1.top();
//        auto u2 = q2.top();
//
//        if (u1.f <= u2.f)
//            break;
//        
//        --botp[u1.s];
//        --topp[u1.s];
//        ++botp[u2.s];
//        ++topp[u2.s];
//        q1.pop();
//        q2.pop();
//    }
    ll minval, maxval;
    int mnp, mxp;
    while (1) {
        mnp = mxp = -1;
        minval = inf;
        maxval = -inf;
        forn(i, n) {
            if (botp[i]) {
                if (maxval < sval[i][ botp[i]-1 ].f + sval[i][ topp[i] ].f) {
                    maxval = sval[i][ botp[i]-1 ].f + sval[i][ topp[i] ].f;
                    mxp = i;
                }
            }
            if (topp[i]<m-1) {
                if (minval > sval[i][ botp[i] ].f + sval[i][ topp[i]+1 ].f) {
                    minval = sval[i][ botp[i] ].f + sval[i][ topp[i]+1 ].f;
                    mnp = i;
                }
            }
        }

        if (minval >= maxval)
            break;
        --botp[mxp];
        --topp[mxp];
        ++topp[mnp];
        ++botp[mnp];
    }

    forn(i,n) {
        assert(botp[i]>=0);
        assert(topp[i]>=0);
        assert(botp[i]<=m-1);
        assert(topp[i]<=m-1);
        assert(m-1 + botp[i] - topp[i] == k);
    }

    ll ans = 0;
    forn(i ,n) {
        for(int j = m-1; j > topp[i]; --j) c[ i*m + sval[i][j].s ] = 1;
        for(int j = m-1; j > topp[i]; --j) ans += sval[i][j].f;
        for(int j = 0; j < botp[i]; ++j)  z[ i*m + sval[i][j].s ] = 1;
        for(int j = 0; j < botp[i]; ++j)  ans -= sval[i][j].f;
    }

    forn(i,n) {
        topp[i] = m-1;
        botp[i] = 0;
    }

    bitset<N> up;
    int cnt;
    int u = 0;
    int str = 0;
    int ind;
    queue<int> b[N];
    queue<int> t[N];
    while (u < k) {
        cnt = 0;
        forn(i,n) up[i] = 0;
        while (cnt < (n>>1)) {
            assert(str < sz(vals));
            ind = vals[str].s;
            ++str;
            if (c[ ind ]) {
                t[ind/m].push(ind);
                if (!up[ind/m]) {
                    up[ind/m] = 1;
                    ++cnt;
                }
            }

            if (z[ ind ]) {
                b[ind/m].push(ind);
            }
        }
        
        forn(i,n) {
            if (up[i]) {
                s[i][t[i].front()%m] = u;
                t[i].pop();
            } else {
                s[i][b[i].front()%m] = u;
                t[i].pop();
            }
        }
        ++u;
    }

    allocate_tickets(s);

    return ans;
}


ll find_maximum(int k, vector<vi>x) {
    int n = sz(x);
    int m = sz(x[0]);
//    if (m == 1) return subtask1(k,x);
//    if (k == 1) return subtask2(k,x);
    if (m == k) return subtask4(k,x);

    return subtaskidk(k,x);
}

#ifdef ONPC
void allocate_tickets(vector<vi>s) {
    forn(i, sz(s)) {
        forn(j, sz(s[0])) {
            cout << s[i][j] << ' ';
        }
        cout << endl;
    }
}

void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    vector<vi> x(n);
    forn(i,n) {
        x[i].assign(m,0);
    }

    forn(j,m) {
        forn(i,n) {
            cin >> x[i][j];
        }
    }

    cout << find_maximum(k, x) << endl;
}

int main() {
    freopen("in", "r", stdin);
//    ios_base::sync_with_stdio(0);cin.tie(0);
    solve();
}
#endif

Compilation message (stderr)

tickets.cpp: In function 'll find_maximum(int, std::vector<std::vector<int> >)':
tickets.cpp:394:9: warning: unused variable 'n' [-Wunused-variable]
  394 |     int n = sz(x);
      |         ^
#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...