codeforces 665E (字典樹)
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
Help ZS the Coder find the number of beautiful subarrays of a!
Input
The first line contains two integers n and k (1 ≤ n ≤ 106, 1 ≤ k ≤ 109
The second line contains n integers ai (0 ≤ ai ≤ 109) — the elements of the array a.
OutputPrint the only integer c — the number of beautiful subarrays of the array a.
Examples input3 1
1 2 3
output
5
input3 2
1 2 3
output
3
input
3 3
1 2 3
output
2
題意:求出一個數組的子串使得這個子串的xor值大於等於k.
先求出每一段字首和,等價於求多少對字首的xor大於等於k.把字首掃一遍,每次用利用
字首的值和k跑字典樹,字首num和k的某一位上有4種情況,我就懶得找統一的規律了
直接討論:
1:num和k都是1,往字典樹當前節點的next[0]走;
2:num和k都是0,字典樹當前節點next[1]子樹的size和向next[1]走的結果相加;
3:num是1,k是0,字典樹當前節點next[0]子樹的size和向next[0]走的結果相加;
4:num是0,k是1,往字典樹當前節點的next[1]走;
然後每次統計完把num插進字典樹,更新每個節點一下的數字個數.
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
#define maxn 1111111
int a[maxn];
struct node {
int next[2];
int num;
}tree[maxn*33];
int root, cnt;
int n, k;
void build_node (int c) {
if (!tree[c].next[0])
tree[c].next[0] = ++cnt, tree[tree[c].next[0]].num = 0;
if (!tree[c].next[1])
tree[c].next[1] = ++cnt, tree[tree[c].next[1]].num = 0;
}
int dfs (int u, int bit, int num) {
build_node (u);
if (tree[u].num == 0 && u != root)
return 0;
if (bit == 0) {
return tree[u].num;
}
int ans = 0;
int id1 = ((num&bit)>=1);//num當前位
int id2 = ((k&bit)>=1); //k當前位
if (id1 && id2) {
ans += dfs (tree[u].next[0], bit>>1, num);
}
else if (!id1 && !id2) {
ans += tree[tree[u].next[1]].num + dfs (tree[u].next[0], bit>>1, num);
}
else if (id1 && !id2) {
ans += tree[tree[u].next[0]].num + dfs (tree[u].next[1], bit>>1, num);
}
else {
ans += dfs (tree[u].next[1], bit>>1, num);
}
return ans;
}
void insert (int num) {
int p = root;
int bit = (1<<30);
while (bit) {
tree[p].num++;
build_node (p);
int id = ((num&bit)>=1);//當前位
p = tree[p].next[id];
bit >>= 1;
}
build_node (p);
tree[p].num++;
}
void solve () {
long long ans = 0;
root = 1;
build_node (root);
for (int i = 1; i <= n; i++) {
int p = root;
if (a[i] >= k)
ans++;
int cur = (1<<30);
int gg = dfs (p, cur, a[i]);
ans += gg;
insert (a[i]);
}
printf ("%lld\n", ans);
}
int main () {
cnt = 1;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
scanf ("%d", &a[i]);
if (i > 1)
a[i] ^= a[i-1];
}
solve ();
return 0;
}