[CF1030E]Vasya and Good Sequences

Posted skylee03

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1030E]Vasya and Good Sequences相关的知识,希望对你有一定的参考价值。

[CF1030E]Vasya and Good Sequences

题目大意:

给定一个长度为(n(nle3 imes10^5))的数列(a_i(1le a_ile10^{18}))。可以任意对若干数进行操作,交换这个数的任意二进制位。求有多少区间,使得这个区间内的数经过操作使得异或和为(0)

思路:

显然这与(a_i)本身的值无关,只与二进制下(1)的个数有关。

一个区间([l,r])需要满足以下条件:

  1. 二进制下(1)的个数为偶数;
  2. 二进制下(1)的个数最多的那个数的(1)的个数不超过剩下的数。

对于条件(1),我们可以很自然地得到一个(mathcal O(n))的做法。

对于条件(2),由于对于每个数,(1)的个数至少是(1),最多不超过(60),所以只需要枚举(60)个即可。

时间复杂度(mathcal O(60n))

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
typedef long long int64;
inline int64 getint() {
    register char ch;
    while(!isdigit(ch=getchar()));
    register int64 x=ch^'0';
    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    return x;
}
const int N=3e5+1;
int c[N],sum[N],cnt[2]={1};
int main() {
    const int n=getint();
    int64 ans=0;
    for(register int i=1;i<=n;i++) {
        c[i]=__builtin_popcountll(getint());
        sum[i]=sum[i-1]+c[i];
        ans+=cnt[sum[i]&1];
        for(register int j=i,k=i+1,max=0;j>=1&&j>=i-61;j--) {
            while(k>j) max=std::max(max,c[--k]);
            if(max*2>sum[i]-sum[j-1]&&(sum[i]%2==sum[j-1]%2)) ans--;
        }
        cnt[sum[i]%2]++;
    }
    printf("%lld
",ans);
    return 0;
}

以上是关于[CF1030E]Vasya and Good Sequences的主要内容,如果未能解决你的问题,请参考以下文章

[CF1065A]Vasya and Chocolate

codeforces 1041 E.Vasya and Good Sequences(暴力?)

[Codeforces 1058E] Vasya and Good Sequences

Codeforces 1053 B - Vasya and Good Sequences

CF1030D Vasya and Triangle 计算几何构造

Codeforces Round #512 E - Vasya and Good Sequences