码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1054D Changing Array

时间:2018-11-04 01:46:29      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:cond   Nging   begin   取值   def   更新   最小化   hang   相同   

Codeforces 1054D Changing Array


做法:给定一个序列,每个数可以把在2进制k位下取反,也可以不变,在改变后,这个序列异或和不为0的区间的个数。考虑如何求出尽可能少的异或为0的序列,对序列求前缀之后,就相当与问这个前缀的序列中,有多少对的值相同,注意还有开始的0。那么对于所有数取值为min(a,~a),现在我们需要最小化,更新后同一种数中出现的相同的数对的个数,即\(C(a,2) + C(w-a,2)\),w是这种数的个数,a是取反的数的个数,当\(a = \frac{w}{2}\)时,答案最小,对于每一种都计算即可。

#include <bits/stdc++.h>
typedef long long ll;
const int N = 2e5 + 7;
using namespace std;
int n, k, lim, a[N];
map<int,int> M;
ll C(ll x) { return x*(x-1LL)>>1LL; }
int main() {
    scanf("%d%d",&n,&k);
    lim = (1ll<<k) - 1ll;
    for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
    for(int i = 2; i <= n; ++i) a[i] ^= a[i-1];
    for(int i = 0; i <= n; ++i) a[i] = min(a[i], lim-a[i]), ++M[a[i]];
    ll ans = C(n+1);
    for(map<int,int>::iterator it = M.begin(); it != M.end(); ++it) {
        int w = (*it).second;
        ans -= C( w>>1 ) + C( w - (w>>1) );
    }
    printf("%lld\n", ans);
    return 0;
}

Codeforces 1054D Changing Array

标签:cond   Nging   begin   取值   def   更新   最小化   hang   相同   

原文地址:https://www.cnblogs.com/RRRR-wys/p/9902824.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!