习题:changing array (贪心)
Posted loney-s
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了习题:changing array (贪心)相关的知识,希望对你有一定的参考价值。
题目
思路
正难则反,全集是很好求的,即为(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;
}
以上是关于习题:changing array (贪心)的主要内容,如果未能解决你的问题,请参考以下文章
我的Android进阶之旅Android Studio 中 使用git提交代码报错:Can‘t commit changes from multiple changelists at once(代码片