1054D&EZOJ #93 Changing Array
分析
我们可以对一个数列求前缀和,如果pre[l]=pre[r]则我们可以知道区间[l,r]一定不合法
于是我们就要让不合法的区间尽量少
我们知道对于一个数$x$,他只受x和$(2^k-1)$^$k$有关
而根据小学奥数所学,当这两个数字的数量最接近是答案最优
详见代码
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
map<int,int>pre;
int main(){
int n,m,i,j,k,s=0;
long long Ans=0;
scanf("%d%d",&n,&k);
m=(1<<k)-1;
pre[0]=1;
for(i=1;i<=n;i++){
int x;
scanf("%d",&x);
s^=x;
k=s^m;
if(pre[k]>pre[s])Ans+=i-pre[s],pre[s]++;
else Ans+=i-pre[k],pre[k]++;
}
cout<<Ans<<endl;
return 0;
}