Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Counting Valid Bitwise XOR Operation Sequences with Equality Constraints

Notes May 15 2

Given an array (a_1, a_2, \ldots, a_n) and three variables (P, Q, R) initially set to zero, process each element sequentially. For each element (a_i), choose one of three operations:

  1. (P := P \oplus a_i)
  2. (Q := Q \oplus a_i)
  3. (R := R \oplus a_i)

After each operation, at least two of (P, Q, R) must be equal. The task is to count the number of valid operation sequneces modulo (10^9 + 7).

Input Format

The input consists of multiple test cases. The first line contains the number of test cases (t). Each test case includes:

  • An integer (n) (array length)
  • (n) integers (a_1, a_2, \ldots, a_n)

Output Format

For each test case, output the count of valid sequences modulo (10^9 + 7).

Solution Approach

Use dynamic programming with a segment tree to track valid states efficiently. The key observation is that the XOR sum of the array elements determines the unique value among (P, Q, R) at each step.

Code Example

#include <bits/stdc++.h>
using namespace std;

const int MOD = 1e9 + 7;
const int MAXN = 2e5 + 5;

struct SegmentTree {
    struct Node { int left, right, sum; };
    vector<Node> nodes;
    int root, nextId;

    SegmentTree() : root(0), nextId(1) { nodes.resize(1); }

    void update(int &id, int l, int r, int pos, int val) {
        if (!id) {
            id = nextId++;
            nodes.emplace_back();
        }
        if (l == r) {
            nodes[id].sum = (nodes[id].sum + val) % MOD;
            return;
        }
        int mid = (l + r) >> 1;
        if (pos <= mid) update(nodes[id].left, l, mid, pos, val);
        else update(nodes[id].right, mid + 1, r, pos, val);
        nodes[id].sum = (nodes[nodes[id].left].sum + nodes[nodes[id].right].sum) % MOD;
    }

    int query(int id, int l, int r, int pos) {
        if (!id) return 0;
        if (l == r) return nodes[id].sum;
        int mid = (l + r) >> 1;
        return pos <= mid ? query(nodes[id].left, l, mid, pos) : query(nodes[id].right, mid + 1, r, pos);
    }

    void clear() {
        root = 0;
        nextId = 1;
        nodes.clear();
        nodes.emplace_back();
    }
};

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

    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int &x : a) cin >> x;

        SegmentTree st;
        st.update(st.root, 0, 1 << 30, 0, 1);
        int xorSum = 0;

        for (int x : a) {
            int val = (st.query(st.root, 0, 1 << 30, xorSum ^ x) + st.query(st.root, 0, 1 << 30, xorSum)) % MOD;
            st.update(st.root, 0, 1 << 30, xorSum, 2 * val % MOD);
            xorSum ^= x;
        }
        cout << st.nodes[st.root].sum << '\n';
    }
    return 0;
}

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.