Submission #1349248

#TimeUsernameProblemLanguageResultExecution timeMemory
1349248SSKMFPairs (IOI07_pairs)C++20
70 / 100
129 ms23920 KiB
#include <bits/stdc++.h>
using namespace std;

void Solve1 ()
{
    int cantitate , limita , lungime;
    cin >> cantitate >> limita >> lungime;

    vector <int> sir(cantitate);
    for (auto& locatie : sir)
        { cin >> locatie; }

    sort(sir.begin() , sir.end());
        
    int64_t modalitati = 0;
    for (int stanga = 0 , dreapta = 0 ; dreapta < cantitate ; dreapta++)
    {
        while (sir[dreapta] - sir[stanga] > limita)
            { stanga++; }

        modalitati += dreapta - stanga;
    }

    cout << modalitati;
}

int arbore[150000];

void Update (int indice , const int termen , const int lungime)
{
    for ( ; indice <= lungime ; indice += (indice & -indice))
        { arbore[indice] += termen; }
}

int Query (int stanga , int dreapta)
{
    stanga--;
    int rezultat = 0;
    while (stanga != dreapta) {
        if (stanga < dreapta) { rezultat += arbore[dreapta]; dreapta ^= (dreapta & -dreapta); }
        else { rezultat -= arbore[stanga]; stanga ^= (stanga & -stanga); }
    }

    return rezultat;
}

void Solve2 ()
{
    int cantitate , limita , lungime;
    cin >> cantitate >> limita >> lungime;

    vector < pair <int , int> > sir(cantitate);
    for (auto& locatie : sir)
    { 
        cin >> locatie.first >> locatie.second;
        
        locatie = {locatie.first + locatie.second - 1 , locatie.first - locatie.second + lungime};
    }

    sort(sir.begin() , sir.end());

    (lungime <<= 1)--;
    int64_t modalitati = 0;
    for (int stanga = 0 , dreapta = 0 ; dreapta < cantitate ; dreapta++)
    {
        while (sir[dreapta].first - sir[stanga].first > limita)
            { Update(sir[stanga].second , -1 , lungime); stanga++; }
            
        modalitati += Query(max(1 , sir[dreapta].second - limita) , min(lungime , sir[dreapta].second + limita));
        Update(sir[dreapta].second , 1 , lungime);
    }

    cout << modalitati;
}

int suma[225][225][225];

void __Update (const int __indice_1 , const int __indice_2 , const int __indice_3 , const int termen , const int lungime)
{
    for (int indice_1 = __indice_1 ; indice_1 <= lungime ; indice_1 += (indice_1 & -indice_1)) {
        for (int indice_2 = __indice_2 ; indice_2 <= lungime ; indice_2 += (indice_2 & -indice_2)) {
            for (int indice_3 = __indice_3 ; indice_3 <= lungime ; indice_3 += (indice_3 & -indice_3)) 
                { suma[indice_1][indice_2][indice_3] += termen; }   
        }   
    }
}

int __Query (const int __stanga_1 , const int __dreapta_1 , const int __stanga_2 , const int __dreapta_2 , const int __stanga_3 , const int __dreapta_3)
{
    int rezultat = 0;
    for (int stanga_1 = __stanga_1 - 1 , dreapta_1 = __dreapta_1 ; stanga_1 != dreapta_1 ; )
    {
        const int factor_1 = (stanga_1 < dreapta_1 ? 1 : -1);
        for (int stanga_2 = __stanga_2 - 1 , dreapta_2 = __dreapta_2 ; stanga_2 != dreapta_2 ; )
        {
            const int factor_2 = (stanga_2 < dreapta_2 ? 1 : -1);
            for (int stanga_3 = __stanga_3 - 1 , dreapta_3 = __dreapta_3 ; stanga_3 != dreapta_3 ; )
            {
                const int factor_3 = (stanga_3 < dreapta_3 ? 1 : -1);
                rezultat += factor_1 * factor_2 * factor_3 * suma[max(stanga_1 , dreapta_1)][max(stanga_2 , dreapta_2)][max(stanga_3 , dreapta_3)];
                if (factor_3 < 0) { stanga_3 ^= (stanga_3 & -stanga_3); }
                else { dreapta_3 ^= (dreapta_3 & -dreapta_3); }
            }
            
            if (factor_2 < 0) { stanga_2 ^= (stanga_2 & -stanga_2); }
            else { dreapta_2 ^= (dreapta_2 & -dreapta_2); }
        }

        if (factor_1 < 0) { stanga_1 ^= (stanga_1 & -stanga_1); }
        else { dreapta_1 ^= (dreapta_1 & -dreapta_1); }
    }

    return rezultat;
}

void Solve3 ()
{
    int cantitate , limita , lungime;
    cin >> cantitate >> limita >> lungime;

    vector < array <int , 4> > sir(cantitate);
    for (auto& locatie : sir)
    { 
        cin >> locatie[0] >> locatie[1] >> locatie[2];

        locatie = {locatie[0] + locatie[1] + locatie[2] , locatie[0] - locatie[1] + locatie[2] + lungime , locatie[0] + locatie[1] - locatie[2] + lungime , locatie[0] - locatie[1] - locatie[2] + 2 * lungime};
    }

    sort(sir.begin() , sir.end());

    (lungime *= 3) -= 2;
    int64_t modalitati = 0;
    for (int stanga = 0 , dreapta = 0 ; dreapta < cantitate ; dreapta++)
    {
        while (sir[dreapta][0] - sir[stanga][0] > limita)
            { __Update(sir[stanga][1] , sir[stanga][2] , sir[stanga][3] , -1 , lungime); stanga++; }

        modalitati += __Query(max(1 , sir[dreapta][1] - limita) , min(lungime , sir[dreapta][1] + limita) , max(1 , sir[dreapta][2] - limita) , min(lungime , sir[dreapta][2] + limita) , max(1 , sir[dreapta][3] - limita) , min(lungime , sir[dreapta][3] + limita));

        __Update(sir[dreapta][1] , sir[dreapta][2] , sir[dreapta][3] , 1 , lungime);
    }

    cout << modalitati;
}

int main ()
{
    ios :: sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int cerinta;
    cin >> cerinta;

    if (cerinta == 1) { Solve1(); }
    else if (cerinta == 2) { Solve2(); }
    else { Solve3(); }
    
    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...
#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...