Submission #429344

#TimeUsernameProblemLanguageResultExecution timeMemory
429344JeanBombeurAliens (IOI16_aliens)C++17
100 / 100
160 ms6656 KiB
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <bits/stdc++.h>
#include "aliens.h"
using namespace std;
 
//    <|°_°|>
 
const int MAX_POINTS = (100 * 1000);
const int LOG = (40);
 
struct droite {
    long long pente, cst;
    int prix;
};
 
pair <long long, long long> Points[MAX_POINTS];
pair <int, int> Aliens[MAX_POINTS];
 
droite Deque[MAX_POINTS];
int deb = 0, fin = 0;
 
int nbPoints = 0;

bool Compare(pair <int, int> a, pair <int, int> b) {
    if (a.first != b.first)
        return a.first < b.first;
    return a.second > b.second;
}

void Insert(droite a) {
    while (fin > deb + 1 && (a.cst - Deque[fin - 1].cst) * (Deque[fin - 2].pente - Deque[fin - 1].pente) < (Deque[fin - 1].pente - a.pente) * (Deque[fin - 1].cst - Deque[fin - 2].cst))
        fin --;
    Deque[fin ++] = a;
    return;
}
 
pair <long long, int> GetMin(long long absc) {
    while (fin > deb + 1 && (absc * Deque[deb].pente + Deque[deb].cst) > (absc * Deque[deb + 1].pente + Deque[deb + 1].cst))
        deb ++;
    return {Deque[deb].pente * absc + Deque[deb].cst, Deque[deb].prix};
}
 
pair <long long, int> FindDP(long long lambda) {
    deb = 0, fin = 0;
    pair <long long, int> DP = {0LL, 0};
    Insert({- 2 * Points[0].first, Points[0].first * Points[0].first, 0});
    for (int i = 0; i < nbPoints; i ++)
    {
        DP = GetMin(Points[i].second);
        DP.first += Points[i].second * Points[i].second + lambda;
        DP.second ++;
        if (i + 1 < nbPoints)
        {
            long long d1 = max(0LL, Points[i].second - Points[i + 1].first), d2 = Points[i + 1].first;
            Insert({-2 * d2, DP.first - d1 * d1 + d2 * d2, DP.second});
        }
    }
    return DP;
}
 
long long take_photos(int nbAliens, int tailleMax, int nbPhotos, vector<int> Lignes, vector<int> Colonnes) {
    
    tailleMax ++;
    
    for (int i = 0; i < nbAliens; i ++)
    {
        if (Lignes[i] > Colonnes[i])
            swap(Lignes[i], Colonnes[i]);
        Aliens[i] = {Lignes[i], ++ Colonnes[i]};
    }
    sort(Aliens, Aliens + nbAliens, Compare);
    
    for (int i = 0; i < nbAliens; i ++)
    {
        if (nbPoints == 0 || Aliens[i].second > (int)Points[nbPoints - 1].second)
            Points[nbPoints ++] = Aliens[i];
    }
    
    long long lambda = -1;
    pair <long long, int> DP;

    for (long long i = (1LL << LOG); i > 0; i /= 2)
    {
        DP = FindDP(lambda + i);
        if (DP.second > nbPhotos)
            lambda += i;
    }
    DP = FindDP(++ lambda);
    return DP.first - lambda * nbPhotos;
}
#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...