Explanation
We can store two variables: one for the XOR of the numbers in group 0 and another for those in group 1. Let's call these and for brevity. This means for queries of type 2, we output either or depending on the parameter.
Type 1 Queries
Let's only consider for now. Say we had to flip when it was initially , so we have to "remove" from . Notice that since XORing is its own inverse (), we can remove from by setting to .
On the other hand, if was a it would become a , and we need to add to . Fascinatingly, setting to does just what we want as well, since !
The logic for goes much the same way, and so the two values are updated the same way: and .
Efficient Updates
To update and , for a given and , we must find the XOR of all that are contained in the range.
This can be done in time by using prefix sums (or prefix XORs in this case).
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;void solve() {int n;cin >> n;vector<int> a(n);for (int i = 0; i < n; i++) { cin >> a[i]; }string s;
Java
import java.io.*;import java.util.StringTokenizer;public class DataStructuresFan {public static void main(String[] args) throws IOException {BufferedReader rd = new BufferedReader(new InputStreamReader(System.in));int testNum = Integer.parseInt(rd.readLine());for (int t = 0; t < testNum; t++) {int n = Integer.parseInt(rd.readLine());StringTokenizer st = new StringTokenizer(rd.readLine());
Python
for _ in range(int(input())):n = int(input())a = list(map(int, input().split()))s = input()g0 = 0g1 = 0# Construct prefix arrayp = [0] * (n + 1)for i in range(1, n + 1):
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!