Resolución del Máximo XOR con Tres Elementos en Chip Factory

En el problema Chip Factory (HDU5536), se proporciona una secuencia de n números enteros. El objetivo es encontrar tres índices distintos i, j y k de tal manera que la expresión (s_i + s_j) XOR s_k se maximice.

El enfoque de fuerza bruta es factible debido al límite de tiempo indulgente de 9 segundos, ya que itera sobre todas las combinaciones triples. Sin embargo, también se puedee emplear un trie binario (01 trie) para optimizar el rendimeinto. Es esencial almacenar los elementos s_i en el trie y realizar consultas sobre (s_j + s_k), en lugar de almacenar (s_i + s_j) y buscar s_k, para evitar teimpos de ejecución excesivos.

Implementación de Fuerza Bruta


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int pruebas;
    cin >> pruebas;
    while (pruebas--) {
        int cantidad;
        cin >> cantidad;
        vector<int> numeros(cantidad);
        for (int idx = 0; idx < cantidad; idx++) {
            cin >> numeros[idx];
        }
        long long maximo = -1;
        for (int a = 0; a < cantidad; a++) {
            for (int b = a + 1; b < cantidad; b++) {
                for (int c = b + 1; c < cantidad; c++) {
                    long long suma_ab = numeros[a] + numeros[b];
                    maximo = max(maximo, suma_ab ^ numeros[c]);
                    long long suma_ac = numeros[a] + numeros[c];
                    maximo = max(maximo, suma_ac ^ numeros[b]);
                    long long suma_bc = numeros[b] + numeros[c];
                    maximo = max(maximo, suma_bc ^ numeros[a]);
                }
            }
        }
        cout << maximo << endl;
    }
    return 0;
}

Solución con Trie Binario (01 Trie)


#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const int MAX_NODOS = 130000;
const int BITS = 31;

struct NodoArbol {
    int contador;
    int subarboles[2];
    void inicializar() {
        contador = 0;
        subarboles[0] = subarboles[1] = -1;
    }
};

NodoArbol trie[MAX_NODOS];
int siguiente_libre;

void insertar(int valor, int raiz) {
    int actual = raiz;
    for (int bit = BITS - 1; bit >= 0; bit--) {
        int digito = (valor >> bit) & 1;
        if (trie[actual].subarboles[digito] == -1) {
            trie[siguiente_libre].inicializar();
            trie[actual].subarboles[digito] = siguiente_libre++;
        }
        actual = trie[actual].subarboles[digito];
        trie[actual].contador++;
    }
}

long long buscar_maximo(int valor, int raiz) {
    int actual = raiz;
    long long resultado = 0;
    for (int bit = BITS - 1; bit >= 0; bit--) {
        int digito = (valor >> bit) & 1;
        int opuesto = 1 - digito;
        if (trie[actual].subarboles[opuesto] != -1 && trie[trie[actual].subarboles[opuesto]].contador > 0) {
            resultado |= (1LL << bit);
            actual = trie[actual].subarboles[opuesto];
        } else {
            actual = trie[actual].subarboles[digito];
        }
    }
    return resultado;
}

void eliminar(int valor, int raiz) {
    int actual = raiz;
    for (int bit = BITS - 1; bit >= 0; bit--) {
        int digito = (valor >> bit) & 1;
        actual = trie[actual].subarboles[digito];
        trie[actual].contador--;
    }
}

int main() {
    int pruebas;
    cin >> pruebas;
    while (pruebas--) {
        int cantidad;
        cin >> cantidad;
        vector<int> datos(cantidad);
        siguiente_libre = 1;
        trie[0].inicializar();
        for (int i = 0; i < cantidad; i++) {
            cin >> datos[i];
            insertar(datos[i], 0);
        }
        long long respuesta = -1;
        for (int i = 0; i < cantidad; i++) {
            eliminar(datos[i], 0);
            for (int j = 0; j < i; j++) {
                if (i == j) continue;
                eliminar(datos[j], 0);
                long long consulta = buscar_maximo(datos[i] + datos[j], 0);
                respuesta = max(respuesta, consulta);
                insertar(datos[j], 0);
            }
            insertar(datos[i], 0);
        }
        cout << respuesta << endl;
    }
    return 0;
}

Etiquetas: C++ trie bitwise-operations algorithm-optimization competitive-programming

Publicado el 6-15 21:58