[codeforces Mail.Ru Cup 2018 Round 1 D][ xor 操作]
Posted mekakucityactor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[codeforces Mail.Ru Cup 2018 Round 1 D][ xor 操作]相关的知识,希望对你有一定的参考价值。
http://codeforces.com/contest/1054/problem/D
题目大意:一个序列a1 a2...an,可以对若干个元素进行取反,使所得的新序列异或和为0的区间个数最多.
题目分析:首先易知每个位置的前缀异或和的值只有两种,因为对元素进行取反时,取偶数个元素异或和不变,奇数个元素就是原值取反.然后由于对一个位置取反,不会影响后面位置与这个位置的前缀异或和相同的位置个数(因为这个位置取反后,后面各个位置的前缀异或和也跟着改变),所以一个位置的改变只会影响与前面位置前缀和相同的个数,所以只需要贪心地根据前面位置值出现次数来进行是否取反该位置的判断.
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<map> 5 #include<cstdio> 6 using namespace std; 7 typedef long long ll; 8 ll q[200005]; 9 map<int ,int>nums; 10 int main(){ 11 ll n,k; 12 cin>>n>>k; 13 for(int i=0;i<n;i++){ 14 scanf("%lld",&q[i]); 15 } 16 ll s=(1<<k)-1; 17 ll res=q[0]; 18 ll ans=(n+1)*n/2; 19 if(res==0){ 20 res^=s; 21 } 22 nums[res]++; 23 for(int i=1;i<n;i++){ 24 ll x1=res^q[i]; 25 ll x2=x1^s; 26 if(x1==0){ 27 if(nums[x1]+1>=nums[x2]){ 28 res=res^q[i]^s; 29 ans-=nums[x2]; 30 nums[x2]++; 31 } 32 else{ 33 res=res^q[i]; 34 ans=ans-nums[x1]-1; 35 nums[x1]++; 36 } 37 } 38 else if(x2==0){ 39 if(nums[x1]>=nums[x2]+1){ 40 res=res^q[i]^s; 41 ans=ans-nums[x2]-1; 42 nums[x2]++; 43 } 44 else{ 45 res=res^q[i]; 46 ans-=nums[x1]; 47 nums[x1]++; 48 } 49 50 } 51 else if(nums[x1]>=nums[x2]){ 52 res=res^q[i]^s; 53 ans-=nums[x2]; 54 nums[x2]++; 55 } 56 else{ 57 res=res^q[i]; 58 ans-=nums[x1]; 59 nums[x1]++; 60 } 61 } 62 cout<<ans<<endl; 63 }
以上是关于[codeforces Mail.Ru Cup 2018 Round 1 D][ xor 操作]的主要内容,如果未能解决你的问题,请参考以下文章
Mail.Ru Cup 2018 Round 3 Solution
[题解]Mail.Ru Cup 2018 Round 1 - A. Elevator or Stairs?
RCC 2017 Qual 1 Mail.Ru, April 2, 2017 (A)
Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem F (Codeforces 831F) - 数论 - 暴力(