#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;
}