One day, ZS the Coder wrote down an array of integers a with elements a1, a2, ..., an.
A subarray of the array a is a sequence al, al + 1, ..., ar for some integers (l, r) such that 1 ≤ l ≤ r ≤ n. ZS the Coder thinks that a subarray of a is beautiful if the bitwise xor of all the elements in the subarray is at least k.
Help ZS the Coder find the number of beautiful subarrays of a!
The first line contains two integers n and k (1 ≤ n ≤ 106, 1 ≤ k ≤ 109) — the number of elements in the array a and the value of the parameter k.
The second line contains n integers ai (0 ≤ ai ≤ 109) — the elements of the array a.
Print the only integer c — the number of beautiful subarrays of the array a.
3 1 1 2 3
5
3 2 1 2 3
3
3 3 1 2 3
2
题意:给以一个序列,问你这个序列有多少个连续子序列的异或和大于等于k。
分析:对序列求出前缀异或和后,问题转化为求序列两个元素的异或和大于等于k,我们把所有数扔进一棵tire中,每次加入新数后在tire中查找一次k,如果当前k的位置为0,那么当前节点的右儿子下的所有数都可以记入答案,最后记得加上异或和等于k的数。
#include <cstdio>
#include <iostream>
#define MAX 30*1000000
using namespace std;
long long ans;
int n,k,a[1000001];
struct trie
{
int ch[MAX][2],tot;
long long val[MAX];
void build()
{
val[0] = 0;
ans = 0;
tot = 1;
}
void insert(int s)
{
int u = 0;
for(int i = 30;i >= 0;i--)
{
int v = ((1<<i) & s) ? 1 : 0;
if(!ch[u][v]) ch[u][v] = tot++;
u = ch[u][v];
val[u]++;
}
}
void find(int s)
{
int u = 0;
for(int i = 30;i >= 0;i--)
{
int v = ((1<<i) & s) ? 1 : 0;
if(((1<<i) & k) == 0)
{
ans += val[ch[u][1 xor v]];
u = ch[u][v];
}
else u = ch[u][1 xor v];
if(!u) break;
}
ans += val[u];
}
} tree;
int main()
{
tree.build();
tree.insert(0);
scanf("%d%d",&n,&k);
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
a[i] = a[i] ^ a[i-1];
tree.find(a[i]);
tree.insert(a[i]);
}
cout<<ans<<endl;
}