Submission #1325013

#TimeUsernameProblemLanguageResultExecution timeMemory
1325013LudisseyFestival (IOI25_festival)C++20
100 / 100
82 ms14620 KiB
#include "festival.h"
#include <bits/stdc++.h>
#define int long long
#define sz(a) (int)a.size()
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
using namespace std;
vector<vector<vector<vector<int>>>> dp;
vector<vector<vector<vector<pair<int,int>>>>> prv;
int n;
vector<vector<pair<int,int>>> v(4);

const int MAX_VAL=1e16;

std::vector<signed> max_coupons(signed _A, std::vector<signed> P, std::vector<signed> T) {
    v.resize(4);
    n=sz(P);
    int A=_A;
    for (int i = 0; i < n; i++) v[T[i]-1].push_back({P[i],i});
    for (int i = 0; i < 4; i++) sort(all(v[i]));
    vector<pair<int,int>> srt;
    for (int i = 0; i < 4; i++) { for (int j = 0; j < sz(v[i]); j++) srt.push_back({i+1,j}); }
    sort(all(srt), [](pair<int,int> a, pair<int,int> b){
        /*cerr <<  v[a.first][a.second].first*a.first*b.first+b.first*v[b.first][b.second].first << " ";
        cerr <<  v[b.first][b.second].first*a.first*b.first+a.first*v[a.first][a.second].first << " ";
        cerr << "\n";*/
        return v[a.first-1][a.second].first*a.first*b.first+b.first*v[b.first-1][b.second].first<v[b.first-1][b.second].first*a.first*b.first+a.first*v[a.first-1][a.second].first;
    });
    int cv[4]={0,0,0,0};
    vector<signed> outp;
    int a=A;
    int lst1=-1;
    int lstv=a;
    for (int i = 0; i < sz(srt); i++)
    {
        srt[i].first--;
        int mxI=srt[i].first;
        if((a-v[mxI][cv[mxI]].first)*(mxI+1)<a) break;
        lstv=a;
        a=(a-v[mxI][cv[mxI]].first)*(mxI+1);
        a=min(MAX_VAL,a);
        outp.push_back(v[mxI][cv[mxI]].second);
        cv[mxI]++;
        lst1=mxI;
    }
    /*if(lst1!=-1) cv[lst1]--;
    a=lstv;*/
    vector<int> pref(sz(v[0]));
    for (int i = 0; i < sz(v[0]); i++)
    {
        pref[i]=v[0][i].first;
        if(i>0) pref[i]+=pref[i-1];
    }
    map<pair<pair<int,int>,int>,int> dp;
    map<pair<pair<int,int>,int>,pair<int,int>> last;
    A=a;
    int mxI[3]={cv[1]+cv[2]+cv[3],cv[1],cv[2]};
    int bk=mxI[0];
    dp[{{mxI[0],mxI[1]},mxI[2]}]=A+1;
    int mx=upper_bound(all(pref), A)-pref.begin();
    queue<pair<pair<int,int>,int>> q;
    q.push({{mxI[0],mxI[1]},mxI[2]});
    while(!q.empty()){
        int k=q.front().first.first;        
        int v1=q.front().first.second;        
        int v2=q.front().second;        
        int v3=k-v1-v2;
        q.pop();
        a=min(MAX_VAL,dp[{{k,v1},v2}]-1);
        int up=upper_bound(all(pref),a)-pref.begin();
        if(up+k>mx){
            mx=up+k;
            mxI[0]=k;
            mxI[1]=v1;
            mxI[2]=v2;
        }
        if(v1<sz(v[1])&&v[1][v1].first<=a){
            int nv=(a-v[1][v1].first)*2;
            if(dp[{{k+1,v1+1},v2}]==0) q.push({{k+1,v1+1},v2});
            if(dp[{{k+1,v1+1},v2}]<nv+1){
                last[{{k+1,v1+1},v2}]={1,v[1][v1].second};
                dp[{{k+1,v1+1},v2}]=nv+1;
            }            
        }
        if(v2<sz(v[2])&&v[2][v2].first<=a){
            int nv=(a-v[2][v2].first)*3;
            if(dp[{{k+1,v1},v2+1}]==0) q.push({{k+1,v1},v2+1});
            if(dp[{{k+1,v1},v2+1}]<nv+1){
                last[{{k+1,v1},v2+1}]={2,v[2][v2].second};
                dp[{{k+1,v1},v2+1}]=nv+1;
            }            
        }
        if(v3<sz(v[3])&&v[3][v3].first<=a){
            int nv=(a-v[3][v3].first)*4;
            if(dp[{{k+1,v1},v2}]==0) q.push({{k+1,v1},v2});
            if(dp[{{k+1,v1},v2}]<nv+1){
                last[{{k+1,v1},v2}]={3,v[3][v3].second};
                dp[{{k+1,v1},v2}]=nv+1;
            }            
        }
    }
    vector<signed> _outp;
    a=dp[{{mxI[0],mxI[1]},mxI[2]}]-1;
    while(mxI[0]>bk){
        _outp.push_back(last[{{mxI[0],mxI[1]},mxI[2]}].second);
        if(last[{{mxI[0],mxI[1]},mxI[2]}].first<3) mxI[last[{{mxI[0],mxI[1]},mxI[2]}].first]--;
        mxI[0]--;
    }
    reverse(all(_outp));
    for (auto u : _outp) outp.push_back(u);

    int v0=0;
    while(v0<sz(v[0])&&a>=v[0][v0].first){
        a-=v[0][v0].first;
        outp.push_back(v[0][v0].second);
        v0++;
    }
    return outp;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...