正题
题目链接:https://www.luogu.com.cn/problem/CF1054D
题目大意
一个长度为nnn的序列,每个数小于2k2^k2k,可以选择一些数xorxorxor上2k−12^k-12k−1。要求使得满足alxoral+1xor...xorar=0a_l\ xor\ a_{l+1}\ xor...xor\ a_r=0al xor al+1 xor...xor ar=0的区间个数最少。
解题思路
首先做前缀xorxorxor,这样就变成了al−1xorar=0a_{l-1}\ xor\ a_r=0al−1 xor ar=0的数量最少,也就算相同的对数最少。
若axor(2k−1)=ba\ xor\ (2^k-1)=ba xor (2k−1)=b或者a=ba=ba=b我们将它们视为同一类,它们可以相互转换,对于每一类我们一半取大的,一半取小的即可。
时间复杂度O(nlogn)O(n\log n)O(nlogn)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=2e5+10;
int n,k,a[N];long long ans;
map<int,int> v;
long long p(int x)
{return 1ll*x*(x-1)/2;}
int main()
{scanf("%d%d",&n,&k);int ms=(1<<k)-1;v[0]++;for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[i]^=a[i-1];if(ms-a[i]>a[i])v[a[i]]++;else v[ms-a[i]]++;}map<int,int>::iterator it=v.begin();ans=1ll*n*(n+1)/2;for(;it!=v.end();it++){int x=it->second;ans-=p(x/2)+p(x-x/2);}printf("%lld\n",ans);return 0;
}