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;
}
posted @ 2018-11-02 11:18  水题收割者  阅读(94)  评论(0编辑  收藏  举报