zoukankan      html  css  js  c++  java
  • Codeforces 1030E 【暴力构造】

    LINK


    题目大意:给你n个数,你可以交换一个数的任意二进制位,问你可以选出多少区间经过操作后异或和是0

    思路

    充分必要条件:

    • 区间中二进制1的个数是偶数
    • 区间中二进制位最多的一个数的二进制个数小于等于和的一半

    然后因为每个数最少会贡献1,所以直接暴力向前跳128位,再之前的就直接前缀和做掉就可以了


    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define IL inline
    #define fu(a,b,c) for(int a=b;a<=c;++a)
    #define fd(a,b,c) for(int a=b;a>=c;--a)
    #define FLIE ""
    IL LL read(){
      LL ans=0,w=1;char c=getchar();
      while(!isdigit(c)&&c!='-')c=getchar();
      if(c=='-')w=-1,c=getchar();
      while(isdigit(c))ans=(ans<<1)+(ans<<3)+c-'0',c=getchar();
      return ans*w;
    }
    #define N 300010
    LL n,a[N];
    LL sum[N],sumj[N],sumo[N];
    LL cnt(LL x){
      LL num=0;
      while(x){
        if(x&1)num++;
        x>>=1;
      }
      return num;
    }
    int main(){
      n=read();
      LL ans=0;
      sumo[0]=1;
      fu(i,1,n)a[i]=read();
      fu(i,1,n){
        a[i]=cnt(a[i]);
        sum[i]=sum[i-1]+a[i];
        LL maxv=a[i];
        fd(j,i-1,max(i-128,1)){
          maxv=max(maxv,a[j]);
          LL tmp=sum[i]-sum[j-1];
          if(maxv*2<=tmp&&tmp%2==0)ans++;
        }
        if(i>129){
          if(sum[i]&1)ans+=sumj[i-130];
          else ans+=sumo[i-130];
        }
        sumj[i]=sumj[i-1]+(sum[i]%2==1);
        sumo[i]=sumo[i-1]+(sum[i]%2==0);
      }
      printf("%I64d",ans);
      return 0;
    }
    
  • 相关阅读:
    ms sql server 2008 简体中文版
    华为交换机集群 介绍
    机房建设标准
    不能打开网页(QQ 微信能上)
    windows下office安装 遇到需要安装msxml 6.0
    Python module (一).psutil
    Python 2 和Python 3 win10 下同时安装 笔记
    windows_程序界面乱码
    IT人员应该掌握的30种技能
    H3C 维护命令
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9695445.html
Copyright © 2011-2022 走看看