Submission #1138948

#TimeUsernameProblemLanguageResultExecution timeMemory
1138948SSKMFKlasika (COCI20_klasika)C++20
110 / 110
4159 ms35896 KiB
#include <bits/stdc++.h>
using namespace std;

const int lungime_bloc = 600;
pair <int , int> arbore[6000000];
struct Operatie { int8_t tip; pair <int , int> valoare; } operatii[200001];
int cantitate , urmatorul[200002] , capat[200002] , inceput[200002] , sfarsit[200002] , valoare[200002];

inline void Parcurgere (const int nod_actual)
{
    inceput[nod_actual] = ++inceput[0];
    for (int indice = capat[nod_actual] ; indice ; indice = urmatorul[indice])
        { Parcurgere(indice); }

    sfarsit[nod_actual] = inceput[0];
}

inline void Insert (int& nod , const int valoare , const int putere)
{
    if (!nod)
        { nod = ++cantitate; }

    if (!putere)
        { return; }

    if (valoare & putere)
        { Insert(arbore[nod].second , valoare , putere >> 1); }
    else
        { Insert(arbore[nod].first , valoare , putere >> 1); }
}

inline int Query (const int nod , const int valoare , const int putere)
{
    if (!putere)
        { return 0; }

    if (valoare & putere) {
        if (arbore[nod].first)
            { return Query(arbore[nod].first , valoare , putere >> 1) | putere; }
        return Query(arbore[nod].second , valoare , putere >> 1);
    }

    if (arbore[nod].second)
        { return Query(arbore[nod].second , valoare , putere >> 1) | putere; }
    return Query(arbore[nod].first , valoare , putere >> 1);
}

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

    int numar_operatii;
    cin >> numar_operatii;

    int lungime = 1;
    for (int indice = 1 ; indice <= numar_operatii ; indice++)
    {
        char tip[8];
        cin >> tip >> operatii[indice].valoare.first >> operatii[indice].valoare.second;
        operatii[indice].tip = tip[0];
        
        if (operatii[indice].tip == 'A') 
        { 
            urmatorul[++lungime] = capat[operatii[indice].valoare.first]; 
            capat[operatii[indice].valoare.first] = lungime;
        }
    }

    Parcurgere(1);

    for (int indice = 2 ; indice <= lungime ; indice++)
        { valoare[indice] = -1; }

    cantitate = lungime / lungime_bloc + 1; lungime = 1;
    for (int indice = 1 ; indice <= numar_operatii ; indice++) {
        if (operatii[indice].tip == 'A')
        {
            lungime++;
            const int actual = (valoare[inceput[operatii[indice].valoare.first]] ^ operatii[indice].valoare.second);
            int temporar = inceput[lungime] / lungime_bloc + 1;
            Insert(temporar , actual , (1 << 30));
            valoare[inceput[lungime]] = actual;
        }
        else
        {
            int maxim = 0;
            int stanga = inceput[operatii[indice].valoare.second];
            int dreapta = sfarsit[operatii[indice].valoare.second];
            const int termen = valoare[inceput[operatii[indice].valoare.first]];
            const int bloc_1 = inceput[operatii[indice].valoare.second] / lungime_bloc + 1;
            const int bloc_2 = sfarsit[operatii[indice].valoare.second] / lungime_bloc + 1;
            if (bloc_1 == bloc_2) {
                for ( ; stanga <= dreapta ; stanga++) {
                    if (valoare[stanga] != -1)
                        { maxim = max(maxim , valoare[stanga] ^ termen); }
                }
            } else {
                for (int indice = bloc_1 * lungime_bloc - 1 ; indice >= stanga ; indice--) {
                    if (valoare[indice] != -1)
                        { maxim = max(maxim , valoare[indice] ^ termen); }
                }
                for (int indice = (bloc_2 - 1) * lungime_bloc ; indice <= dreapta ; indice++) {
                    if (valoare[indice] != -1)
                        { maxim = max(maxim , valoare[indice] ^ termen); }
                }
                for (int indice = bloc_1 + 1 ; indice < bloc_2 ; indice++)
                    { maxim = max(maxim , Query(indice , termen , (1 << 30))); }
            }

            cout << maxim << '\n';
        }
    }

    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...