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; }