CodeForces 1058E

题意略。

思路:本题有两个关键点:

一、满足题设的区间条件

  1.区间内1的个数和为偶数

  2.区间内含1个数最多的那一项,它所含1的个数不得超过区间内1的个数和的一半。

二、长度超过60的区间必然满足上一项的条件2

 

详见代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3e5 + 5;

LL ai[maxn],sum[maxn];
int n,cnt[maxn][2];

LL cnt1(LL x){
    LL ret = 0;
    while(x){
        x = x & (x - 1);
        ++ret;
    }
    return ret;
}

int main(){
    scanf("%d",&n);
    for(int i = 1;i <= n;++i){
        scanf("%lld",&ai[i]);
        sum[i] = ai[i] = cnt1(ai[i]);
        sum[i] += sum[i - 1];
    }
    cnt[0][0] = 1;
    cnt[0][1] = 0;
    LL ans = 0;
    for(int i = 1,j;i <= n;++i){
        cnt[i][sum[i] & 1] = 1;
        cnt[i][1] += cnt[i - 1][1];
        cnt[i][0] += cnt[i - 1][0];
        ans += cnt[i][sum[i] & 1] - 1;
        LL temp = 0,maxx = 0;
        for(j = i;i - j + 1 <= 60 && j >= 1;--j){
            temp += ai[j];
            maxx = max(maxx,ai[j]);
            if(!(temp & 1) && maxx > temp / 2) --ans;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2018-11-25 10:38  温和的提比略  阅读(314)  评论(0编辑  收藏  举报