E. Beautiful Subarrays
Understanding
Solution
前缀和思想,记录前缀异或值s[i],考虑贪心,一个数异或上自己为0,对于一段区间[l~r],异或值=s[l-1]^s[r],证明:s[l-1]^s[r]=s[l-1]^(s[l-1]^s[l~r])=(s[l-1]^s[l-1])^s[l~r]=s[l~r].
一般异或问题用trie树维护,所以,每次吧s[i]丢入trie树,sz记录当前节点的size,统计答案:将k二进制分解,顺着trie走,当前为0,答案+=sz[1](儿子)else 顺着trie树走下去,记得最后统计=的结果。
// <E.cpp> - Sun Oct 9 19:01:04 2016 // This file is made by YJinpeng,created by XuYike's black technology automatically. // Copyright (C) 2016 ChangJun High School, Inc. // I don't know what this program is. #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #define MOD 1000000007 #define INF 1e9 #define IN inline #define RG register using namespace std; typedef long long LL; typedef long double LB; const int MAXN=2e+7; inline int max(int &x,int &y) {return x>y?x:y;} inline int min(int &x,int &y) {return x<y?x:y;} inline LL gi() { register LL w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w; } int c[MAXN][2],s[MAXN],sz[MAXN];LL ans;int k,tot; void insert(int x){ int u=1; for(int i=30;i>=0;i--){ int p=(x>>i)&1; if(!c[u][p])c[u][p]=++tot; sz[u]++;u=c[u][p]; }sz[u]++; } void src(int x){ int u=1; for(int i=30;i>=0;i--){ int p=((x>>i)&1)^1; if(!((k>>i)&1))ans+=sz[c[u][p]],u=c[u][p^1]; else u=c[u][p]; }ans+=sz[u]; } int main() { freopen("E.in","r",stdin); freopen("E.out","w",stdout); int n=gi();k=gi();int now=0;tot=1;insert(0); while(n--){ int a=gi();now^=a; src(now);insert(now); }printf("%lld",ans); return 0; }