Title
大意:给一个区间,询问有多少了区间满足异或和不小于给定的正整数 K K K
Solution
注意一开始trie要插入初始值0
设 s [ i ] s[i] s[i]表示 [ 1 , i ] [1,i] [1,i]的异或和, [ l , r ] [l,r] [l,r]的异或和相当于 s [ r ] x o r s [ l − 1 ] s[r]\ xor\ s[l-1] s[r] xor s[l−1]
可以用 T r i e Trie Trie表示前缀 x o r xor xor和
如何求大于等于 K K K的区间数,可以在查询的时候,强制前面某些位相同,然后反转下一位。
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#define ll long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int N=1e5+5;
int read(){
int p=0,f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
while (isdigit(c)) p=(p<<3)+(p<<1)+c-48,c=getchar();
return p*f;
}
int T;
int n,K;
ll ans,Qw;
struct node{
int t[N][2],cnt[N],tot;
void clear(){
cnt[1]=t[1][1]=t[1][0]=0; tot=1;
}
void insert(int x){
int p=1;
for(int i=29;~i;--i){
int w=(x>>i)&1;
if (!t[p][w]){
t[p][w]=++tot; cnt[tot]=0; t[tot][0]=t[tot][1]=0;
}
++cnt[p],p=t[p][w];
}
++cnt[p];
}
ll query(int x){
int p=1; ll sum=0;
for(int i=29;~i;--i){
if (!p) return sum;
if ((x>>i)&1){
if ((K>>i)&1) p=t[p][0];
else sum+=cnt[t[p][0]],p=t[p][1];
} else {
if ((K>>i)&1) p=t[p][1];
else sum+=cnt[t[p][1]],p=t[p][0];
}
}
return sum+cnt[p];
}
}Trie;
int main(){
freopen("xor.in","r",stdin);
freopen("xor.out","w",stdout);
T=read();
while (T--){
Trie.clear();
n=read(),K=read();
ans=Qw=0; Trie.insert(Qw);
rep(i,1,n) {
Qw^=read();
ans+=Trie.query(Qw);
Trie.insert(Qw);
}
printf("%lld\n",ans);
}
return 0;
}