XOR and Favorite Number (Codeforces 617E)
Tags: Others, data structures

Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pair li and ri and asks you to count the number of pairs of integers i and j, such that l ≤ i ≤ j ≤ r and the xor of the numbers ai, ai + 1, ..., aj is equal to k.

Input: The first line of the input contains integers n, m and k (1 ≤ n, m ≤ 100 000, 0 ≤ k ≤ 1 000 000) — the length of the array, the number of queries and Bob's favorite number respectively.The second line contains n integers ai (0 ≤ ai ≤ 1 000 000) — Bob's array.Then m lines follow. The i-th line contains integers li and ri (1 ≤ li ≤ ri ≤ n) — the parameters of the i-th query.

Output: Print m lines, answer the queries in the order they appear in the input. 

Note: In the first sample the suitable pairs of i and j for the first query are: (1, 2), (1, 4), (1, 5), (2, 3), (3, 6), (5, 6), (6, 6). Not a single of these pairs is suitable for the second query.In the second sample xor equals 1 for all subarrays of an odd length.

Sample Inputs:
6 2 3
1 2 1 1 0 3
1 6
3 5

5 3 1
1 1 1 1 1
1 5
2 4
1 3

Sample Outputs:
7
0

9
4
4

Solution (Python):
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = 'x' in file.mode or 'r' not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b'\n') + (not b)
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            (self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode('ascii'))
        self.read = lambda : self.buffer.read().decode('ascii')
        self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import ceil

def prod(a, mod=10 ** 9 + 7):
    ans = 1
    for each in a:
        ans = ans * each % mod
    return ans

def gcd(x, y):
    while y:
        (x, y) = (y, x % y)
    return x

def lcm(a, b):
    return a * b // gcd(a, b)

def binary(x, length=16):
    y = bin(x)[2:]
    return y if len(y) >= length else '0' * (length - len(y)) + y
for _ in range(int(input()) if not True else 1):
    (n, m, k) = map(int, input().split())
    a = list(map(int, input().split()))
    pre = [0]
    for i in range(n):
        pre += [a[i] ^ pre[-1]]
    BLOCK_SIZE = 320
    queries = [[] for __ in range(BLOCK_SIZE)]
    ans = [0] * m
    for i in range(m):
        (l, r) = map(int, input().split())
        queries[l // BLOCK_SIZE] += [[l - 1, r, i]]
    count = [0] * (1 << 20)
    for i in range(len(queries)):
        queries[i] = sorted(queries[i], key=lambda x: x[1])
        if not queries[i]:
            continue
        left = right = BLOCK_SIZE * i
        count[pre[left]] += 1
        res = 0
        for (l, r, index) in queries[i]:
            while right < r:
                right += 1
                res += count[pre[right] ^ k]
                count[pre[right]] += 1
            while left < l:
                left += 1
                count[pre[left - 1]] -= 1
                res -= count[pre[left - 1] ^ k]
            while left > l:
                left -= 1
                res += count[pre[left] ^ k]
                count[pre[left]] += 1
            ans[index] = res
        while left <= right:
            left += 1
            count[pre[left - 1]] -= 1
            res -= count[pre[left - 1] ^ k]
        assert res == 0
    for each in ans:
        print(each)

Solution (Python):
import sys
readline = sys.stdin.readline

def Mo(N, Q, query):
    D = max(1, int(N / Q ** 0.5))
    mo = [[] for d in range((N + D - 1) // D + 1)]
    for (q, (l, r)) in enumerate(query):
        mo[l // D].append(q)
    retu = []
    for d in range((N + D - 1) // D + 1):
        retu += sorted(mo[d], reverse=d % 2, key=lambda q: query[q][1])
    return retu
(N, Q, K) = map(int, readline().split())
A = [0] + list(map(int, readline().split()))
for i in range(1, N + 1):
    A[i] ^= A[i - 1]
query = []
for q in range(Q):
    (l, r) = map(int, readline().split())
    l -= 1
    query.append((l, r))
(L, R) = (0, 0)
ans = 0
cnt = [0] * (1 << 20)
ans_lst = [None] * Q
for q in Mo(N, Q, query):
    (l, r) = query[q]
    while l < L:
        L -= 1
        ans += cnt[A[L] ^ K]
        cnt[A[L]] += 1
    while R < r + 1:
        ans += cnt[A[R] ^ K]
        cnt[A[R]] += 1
        R += 1
    while L < l:
        cnt[A[L]] -= 1
        ans -= cnt[A[L] ^ K]
        L += 1
    while r + 1 < R:
        R -= 1
        cnt[A[R]] -= 1
        ans -= cnt[A[R] ^ K]
    ans_lst[q] = ans
print(*ans_lst, sep='\n')

Solution (Python):
def solve_queries(n, m, k, a, queries):
    block = int(n ** 0.5) + 1
    ans = [0] * m
    xor = [0] * (n + 1)
    count = [0] * (10 ** 7 + 100)
    for i in range(1, n + 1):
        xor[i] = xor[i - 1] ^ a[i]
    query_blocks = [[] for _ in range(block)]
    for i in range(m):
        (l, r) = queries[i]
        query_blocks[l // block].append((l - 1, r, i))
    for block_queries in query_blocks:
        if not block_queries:
            continue
        block_queries.sort(key=lambda x: x[1])
        left = right = block_queries[0][0]
        count[xor[left]] += 1
        res = 0
        for (l, r, ind) in block_queries:
            while r > right:
                right += 1
                res += count[xor[right] ^ k]
                count[xor[right]] += 1
            while l > left:
                count[xor[left]] -= 1
                res -= count[xor[left] ^ k]
                left += 1
            while l < left:
                left -= 1
                res += count[xor[left] ^ k]
                count[xor[left]] += 1
            ans[ind] = res
        while left <= right:
            count[xor[left]] -= 1
            res -= count[xor[left] ^ k]
            left += 1
    return ans
(n, m, k) = map(int, input().split())
a = [0] + list(map(int, input().split()))
queries = []
for _ in range(m):
    (l, r) = map(int, input().split())
    queries.append((l, r))
results = solve_queries(n, m, k, a, queries)
for result in results:
    print(result)