Submission #1370635

#TimeUsernameProblemLanguageResultExecution timeMemory
1370635vicente1축제 (IOI25_festival)C++20
0 / 100
96 ms113200 KiB
#include <bits/stdc++.h>
using namespace std;
template <typename T>
using v = vector<T>;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using vll = vector<ll>;
using ui = unsigned int;
using vpii = vector<pii>;
using vvi = vector<vi>;

#define pb push_back
#define all(_) _.begin(), _.end()

constexpr int MXN = 200003;
constexpr ll INF = 200000000000000;
constexpr int MOD = 1;
constexpr int LOG = bit_width(ui(MXN));

int n, k;

struct c{
    int t, p, id;
    c(int a, int b, int c_){
        t = a;
        p = b;
        id = c_;
    }
};

vi answ;
vpii T1;
v<c> M1, M;
__int128 X;

ll dp[MXN][67];
bool comp(c x, c y){
    return (ll)x.p*x.t*y.t - (ll)y.t*y.p < (ll)y.p*y.t*x.t - (ll)x.t*x.p;
}

bool win_win(){
    k=0;
    
    while(k<n){
        auto [t,p,id] = M1[k];
        __int128 next = (X-p)*t;
        if(next >= INF){
            answ.clear();
            for(auto &[t,p,id] : M1) answ.pb(id);
            for(auto &[p, id]: T1) answ.pb(id);
            return true;
        }
        if(next >= X){
            answ.pb(id);
            X = next;
            k++;
        }
        else break;
    }
    return false;
}

void retrieve(int comprado){

    vi v;

    while(n && comprado){
        ll prev = dp[n-1][comprado-1];
        ll actual = dp[n][comprado];
        auto [t,p, id] = M[n-1];
        if(actual == (prev-p)*t){
            v.pb(id);
            comprado--;
        }
        n--;
    }

    reverse(all(v));
    answ.insert(answ.begin(), all(v));
}

vi max_coupons(int A, vi P, vi T){
    
    X = A;

    n = T.size();
    
    for(int i=0; i<n; i++){
        if(T[i] == 1) T1.pb({P[i], i});
        else{
            M1.pb(c(T[i],P[i],i));
        }
    }

    vll pref(T1.size());
    bool hayT1 = 0;
    if(T1.size()){
        hayT1 = 1;
        pref[0] = T1[0].first;
        for(int i=1; i<T1.size(); i++) pref[i] = pref[i-1] + T1[i].first;
    }

    sort(all(T1));
    sort(all(M1), comp);

    n = M1.size();

    if(win_win()) return answ;

    M.insert(M.end(), M1.begin()+k, M1.end());

    for(int i=0; i<MXN; i++){
        for(int j=0; j<67; j++) dp[i][j] = -1;
    }

    n = M.size();

    for(int i=0; i<=n; i++){
        dp[i][0] = X;
    }

    for(int i=1; i<=n; i++){
        int tope = min(66, i);
        auto [t, p, id] = M[i-1];
        for(int j=1; j<=tope; j++){
            ll prev = dp[i-1][j-1];
            ll neww = prev >= p ? (prev-p)*t : -1;
            dp[i][j] = max(dp[i-1][j], neww);
        }
    }

    int MX_T1 = 0;
    int MX_other = 0;

    for(int i=0; i<67; i++){
        ll sobra = dp[n][i];
        if(sobra < 0) continue;
        ll extra = hayT1 ? upper_bound(all(pref), sobra) - pref.begin() : 0;
        if(i + extra > MX_T1 + MX_other){
            MX_T1 = extra;
            MX_other = i;
        }
    }

    retrieve(MX_other);

    for(int i=0; i<MX_T1; i++) answ.pb(T1[i].second);

    return answ;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...