Submission #63111

#TimeUsernameProblemLanguageResultExecution timeMemory
63111ArturgoCultivation (JOI17_cultivation)C++11
80 / 100
2049 ms9412 KiB
#include <iostream> #include <queue> #include <map> #include <vector> #include <algorithm> #include <list> #include <set> #include <cassert> using namespace std; int nbLigs, nbCols; vector<pair<int, int>> points; struct pfile { int deb, fin; pair<long long, int> elems[1000]; inline void vide() { deb = fin = 0; } inline void ajoute(long long date, int val) { while(deb != fin && elems[fin - 1].second <= val) { fin--; } elems[fin++] = {date, val}; } inline int taille() { return fin - deb; } inline void supprime(long long date) { while(deb != fin && elems[deb].first <= date) deb++; } inline int maximum() { if(deb == fin) return 2000*1000*1000; return elems[deb].second; } }; struct max_ecart { map<int, int> positions; priority_queue<pair<int, int>> ecarts; max_ecart() { positions[-1]++; positions[nbLigs]++; ecarts.push({nbLigs + 1, -1}); } int tr(int dist) { if(dist == nbLigs) return 2000 * 1000 * 1000; return dist; } void ajoute(int pos) { auto it = positions.lower_bound(pos); int deb, fin; fin = it->first; it--; deb = it->first; positions[pos]++; ecarts.push({fin - pos, pos}); ecarts.push({pos - deb, deb}); } int minN() { auto it = positions.begin(); it++; return tr(it->first); } int minS() { auto it = positions.rbegin(); it++; return tr(nbLigs - it->first - 1); } int minTot() { while(!ecarts.empty()) { pair<int, int> t = ecarts.top(); if(positions.find(t.second) != positions.end() && positions.upper_bound(t.second)->first == t.first + t.second) { return tr(t.first - 1); } else { ecarts.pop(); } } return 2000 * 1000 * 1000; } }; struct Inter { long long taille; int minN, minS, minTot; }; Inter dyn_inters[300][300]; void precalcule_ecarts() { for(int iDeb = 0;iDeb < (int)points.size();iDeb++) { max_ecart curEcarts; for(int iFin = iDeb;iFin < (int)points.size();iFin++) { curEcarts.ajoute(points[iFin].first); Inter nouv; nouv.minN = curEcarts.minN(); nouv.minS = curEcarts.minS(); nouv.minTot = curEcarts.minTot(); dyn_inters[iDeb][iFin] = nouv; } } } pfile minS, minN, minTot; long long traite(long long dist) { vector<Inter> intervalles; Inter debut; debut.minN = debut.minS = debut.minTot = 2000 * 1000 * 1000; intervalles.push_back(debut); long long derDeb = -1000 * 1000 * 1000; int debInd = 0, finInd = 0; int iDebut = 0, iFin = 0; while(iDebut != (int)points.size() || iFin != (int)points.size()) { long long minTemps = (long long)4000 * 1000 * 1000; if(iDebut != (int)points.size()) minTemps = min<long long>(minTemps, points[iDebut].second); if(iFin != (int)points.size()) minTemps = min<long long>(minTemps, points[iFin].second + dist); intervalles.back().taille = minTemps - derDeb; derDeb = minTemps; while(iDebut != (int)points.size() && points[iDebut].second == minTemps) { finInd++; iDebut++; } while(iFin != (int)points.size() && points[iFin].second + dist == minTemps) { debInd++; iFin++; } Inter nouv; if(debInd == finInd) { nouv.minS = nouv.minN = nouv.minTot = 1000 * 1000 * 1000; } else { nouv = dyn_inters[debInd][finInd - 1]; } intervalles.push_back(nouv); } intervalles.back().taille = 1000 * 1000 * 1000; long long minPrix = 2000 * 1000 * 1000; long long posFin = 0, posDeb = 0; int fin = 1; minS.vide(); minN.vide(); minTot.vide(); for(int deb = 1;fin < (int)intervalles.size() - 1;) { if(posFin - posDeb < nbCols) { posFin += intervalles[fin].taille; minS.ajoute(posFin, intervalles[fin].minS); minN.ajoute(posFin, intervalles[fin].minN); minTot.ajoute(posFin, intervalles[fin].minTot); fin++; } if(posFin - posDeb >= nbCols) { minPrix = min<long long>(minPrix, max(minS.maximum() + minN.maximum(), minTot.maximum())); posDeb += intervalles[deb].taille; minS.supprime(posDeb); minN.supprime(posDeb); minTot.supprime(posDeb); deb++; } } return minPrix + dist - 1; } int main() { ios_base::sync_with_stdio(false); cin >> nbCols >> nbLigs; int nbPoints; cin >> nbPoints; for(int iPoint = 0;iPoint < nbPoints;iPoint++) { int lig, col; cin >> lig >> col; points.push_back({col - 1, lig - 1}); } sort(points.begin(), points.end(), [](const pair<int, int>&a, const pair<int, int>&b){return a.second < b.second;}); set<int> distancesCol; distancesCol.insert(1); distancesCol.insert(nbCols); distancesCol.insert(2 * nbCols); for(int iPointA = 0;iPointA < nbPoints;iPointA++) { for(int iPointB = 0;iPointB < nbPoints;iPointB++) { distancesCol.insert(abs(points[iPointA].second - points[iPointB].second)); distancesCol.insert(abs(nbCols - points[iPointA].second + points[iPointB].second)); } } precalcule_ecarts(); long long minTotal = 2000 * 1000 * 1000; for(int dist : distancesCol) { if(dist >= 1) { minTotal = min(minTotal, traite(dist)); } } cout << minTotal << endl; return 0; }
#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...