• [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;
    }
    
  • 相关阅读:
    转&nbsp;子查询
    260@365
    线程池
    转&nbsp;nio&nbsp;&nbsp;&nbsp;&nbsp;netty
    正则表达式匹配标签内的内容
    express接受ajax的发送post请求
    如何查看代码使用率
    ajax传文件用express的multer接住
    ajax 的post方法 的content-type设置和express里应用body-parser
    webpack4 es6转换
  • 原文地址:https://www.cnblogs.com/skylee03/p/9740195.html
Copyright © 2020-2023  润新知