Submission #806673

#TimeUsernameProblemLanguageResultExecution timeMemory
806673oscar1fCake 3 (JOI19_cake3)C++17
100 / 100
675 ms199156 KiB
#include<bits/stdc++.h> using namespace std; #define int long long using pii=pair<int,int>; string to_string(string s) { return s; } template <typename T> string to_string(T v) { bool first = true; string res = "["; for (const auto &x : v) { if (!first) res += ", "; first = false; res += to_string(x); } res += "]"; return res; } template <typename A, typename B> string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } void dbg_out() { cout << endl; } template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << to_string(H); dbg_out(T...); } #ifdef DEBUG #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define dbg(...) #endif struct noeud{ int minVal,maxVal,pos; noeud *filsGauche=nullptr,*filsDroit=nullptr; vector<int> cumuGauche,cumuVal,cumuDroite; noeud (vector<int> listeVal) { assert(!listeVal.empty()); minVal = *min_element(listeVal.begin(), listeVal.end()); maxVal = *max_element(listeVal.begin(), listeVal.end()); //dbg(minVal,maxVal,listeVal); cumuVal.push_back(0); for (auto x:listeVal) { cumuVal.push_back(x+cumuVal.back()); } int taille=listeVal.size(); if (minVal!=maxVal) { int mid=(minVal+maxVal)/2; vector<int> listeGauche,listeDroite; cumuGauche.push_back(0); cumuDroite.push_back(0); for (int x:listeVal) { int estGauche; if (x<=mid) { estGauche=1; listeGauche.push_back(x); } else { estGauche=0; listeDroite.push_back(x); } cumuGauche.push_back(cumuGauche.back()+estGauche); cumuDroite.push_back(cumuDroite.back()+1-estGauche); } if (!listeGauche.empty()) { filsGauche=new noeud(listeGauche); } if (!listeDroite.empty()) { filsDroit=new noeud(listeDroite); } } else { cumuGauche.resize(taille+1,0); cumuDroite.resize(taille+1,0); } } pair<int,int> somMax(int deb,int fin,int nbVal) { if (deb>fin) { return {0,0}; } else if (fin-deb+1<=nbVal || minVal == maxVal) { int nouvDeb = max(deb, fin-nbVal+1); //s.t. fin-nd+1 = nbVal int somme = cumuVal[fin+1]-cumuVal[nouvDeb]; return {somme, fin-nouvDeb+1}; } //int nbGauche=cumuGauche[fin+1]-cumuGauche[deb]; //int nbDroite=cumuDroite[fin+1]-cumuDroite[deb]; int debGauche=cumuGauche[deb]; int finGauche=cumuGauche[fin+1]-1; int debDroite=cumuDroite[deb]; int finDroite=cumuDroite[fin+1]-1; int somDroit=0,cntDroit=0,somGauche=0,cntGauche=0; if (filsDroit!=nullptr) { tie(somDroit,cntDroit)=filsDroit->somMax(debDroite,finDroite,nbVal); nbVal-=cntDroit; } if (nbVal>0 and filsGauche!=nullptr) { tie(somGauche,cntGauche)=filsGauche->somMax(debGauche,finGauche,nbVal); } dbg(somDroit,somGauche,cntDroit,cntGauche); return {somDroit+somGauche,cntDroit+cntGauche}; } }; const int INFINI=(int)1000*1000*1000*1000*1000*1000; int nbPossi,tailleCol,prix,benef,rep; noeud *racine; vector<pair<int,int>> possi; int somMax(int deb,int fin,int nbVal) { return racine->somMax(deb,fin,nbVal).first; } int calcMeil(int deb,int fin) { return possi[deb].second+possi[fin].second-2*(possi[fin].first-possi[deb].first)+somMax(deb+1,fin-1,tailleCol-2); } void calc(int minDeb,int maxDeb,int minFin,int maxFin) { if (maxDeb<minDeb or maxFin<minFin) { return; } int deb=(minDeb+maxDeb)/2; pii record={-INFINI,maxFin}; dbg(deb); for (int i=minFin;i<=maxFin;i++) { if (i-deb+1>=tailleCol) { dbg(deb,i); record=max(record,{calcMeil(deb,i),i}); } } rep=max(rep,record.first); calc(minDeb,deb-1,minFin,record.second); calc(deb+1,maxDeb,record.second,maxFin); } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin>>nbPossi>>tailleCol; for (int i=0;i<nbPossi;i++) { cin>>benef>>prix; possi.push_back({prix,benef}); } sort(possi.begin(),possi.end()); vector<int> listeCoul; for (auto [_,coul]:possi) { listeCoul.push_back(coul); } rep=-INFINI; racine=new noeud(listeCoul); calc(0,nbPossi-1,0,nbPossi-1); cout<<rep<<endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...