题目
思路
正难则反,全集是很好求的,即为\(\frac{n*(n+1)}{2}\),想要异或不为0的尽可能的多,即异或为0的尽可能的少
对于所有的区间\(l,r\),可以用前缀和\(s\)来表示,\(s_r ~xor~s_{l-1}\),
之后我们考虑\(xor\)的性质,只有当两个数相同时,异或值才为0
我们设\(t_k\)表示有多少个前缀和为\(k\)
对于第\(i\)个数,我们贪心的考虑就好了,看是不异或少,还是异或之后少就行了
贪心的正确性显然
\(t_0\)初始值应为1,因为你还要算他本身的贡献
代码
#include<iostream> #include<map> using namespace std; int n,k; int a[200005]; map<int,int> t; int _last; long long ans; int main() { ios::sync_with_stdio(false); cin>>n>>k; k=(1<<k)-1; ans=1ll*(n+1)*n/2; for(int i=1;i<=n;i++) cin>>a[i]; t[0]=1; for(int i=1;i<=n;i++) { int u=a[i]^_last,v=a[i]^k^_last; if(t[u]<t[v]) { ans-=t[u]; t[u]++; _last=u; } else { ans-=t[v]; t[v]++; _last=v; } } cout<<ans; return 0; }
来源:https://www.cnblogs.com/loney-s/p/12246006.html