/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 4ms 532.0 KiB

Code

#include <iostream>
#include <vector>
#include <numeric>

// Set a constant for the number of bits to consider for the integers.
// 10^9 is less than 2^30, so 30 bits are sufficient.
const int MAX_BITS = 30;

/**
 * @brief Represents a node in the Trie.
 * Each node has two children (for bits 0 and 1) and a count of numbers
 * passing through it.
 */
struct TrieNode {
    TrieNode* children[2];
    int count;

    TrieNode() {
        children[0] = nullptr;
        children[1] = nullptr;
        count = 0;
    }
};

/**
 * @brief Inserts a number into the Trie.
 * @param root The root of the Trie.
 * @param num The integer to insert.
 */
void insert(TrieNode* root, int num) {
    TrieNode* node = root;
    for (int i = MAX_BITS; i >= 0; --i) {
        int bit = (num >> i) & 1;
        if (node->children[bit] == nullptr) {
            node->children[bit] = new TrieNode();
        }
        node = node->children[bit];
        node->count++;
    }
}

/**
 * @brief Queries the Trie to find the number of stored values U such that C < (V ^ U).
 * @param root The root of the Trie.
 * @param C The value i ^ A_i.
 * @param V The value i.
 * @return The number of values U satisfying the condition.
 */
long long query(TrieNode* root, int C, int V) {
    long long count = 0;
    TrieNode* node = root;
    for (int i = MAX_BITS; i >= 0; --i) {
        if (node == nullptr) {
            break;
        }

        int c_bit = (C >> i) & 1;
        int v_bit = (V >> i) & 1;

        if (c_bit == 0) {
            // We need the result bit (v_bit ^ u_bit) to be 1.
            // This happens when u_bit = 1 ^ v_bit.
            // All numbers in this sub-tree will satisfy the inequality at this bit.
            int u_bit_gt = 1 ^ v_bit;
            if (node->children[u_bit_gt] != nullptr) {
                count += node->children[u_bit_gt]->count;
            }

            // Continue down the path where the bits are equal to check lower-order bits.
            // (v_bit ^ u_bit) == 0 happens when u_bit = v_bit.
            node = node->children[v_bit];
        } else { // c_bit == 1
            // We cannot be strictly greater at this bit.
            // We must follow the path where the bits are equal.
            // (v_bit ^ u_bit) == 1 happens when u_bit = 1 ^ v_bit.
            node = node->children[1 ^ v_bit];
        }
    }
    return count;
}

/**
 * @brief Deallocates the memory used by the Trie.
 * @param node The current node to deallocate.
 */
void deleteTrie(TrieNode* node) {
    if (node == nullptr) {
        return;
    }
    deleteTrie(node->children[0]);
    deleteTrie(node->children[1]);
    delete node;
}


/**
 * @brief Solves a single test case.
 */
void solve() {
    int n;
    std::cin >> n;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        std::cin >> a[i];
    }

    TrieNode* root = new TrieNode();
    long long total_good_pairs = 0;

    // Iterate i from n down to 1. For each i, the Trie contains
    // values for all j > i.
    for (int i = n; i >= 1; --i) {
        // The problem uses 1-based indexing for i, but the array is 0-indexed.
        int current_A = a[i - 1];
        
        int C = i ^ current_A; // This is i XOR A_i
        int V = i;             // This is i
        
        // Query the trie for j > i that satisfy (i^A_i) < (i^A_j^j)
        total_good_pairs += query(root, C, V);
        
        // Insert C = i^A_i into the trie for subsequent queries (i' < i).
        insert(root, C);
    }
    
    std::cout << total_good_pairs << std::endl;
    
    // Clean up the memory allocated for the Trie
    deleteTrie(root);
}

int main() {
    // Fast I/O for performance
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    int t;
    std::cin >> t;
    while (t--) {
        solve();
    }

    return 0;
}

Information

Submit By
Type
Pretest
Problem
P1198 E. Good Signal Pairs
Language
C++17 (G++ 13.2.0)
Submit At
2025-06-13 17:51:17
Judged At
2025-06-13 17:51:17
Judged By
Score
10
Total Time
4ms
Peak Memory
532.0 KiB