1. 程式人生 > >Codeforces Round #512(Technocup 2019 Elimination Round 1) E. Vasya and Good Seque (Codeforces 1030E)

Codeforces Round #512(Technocup 2019 Elimination Round 1) E. Vasya and Good Seque (Codeforces 1030E)

題目:Vasya and Good Sequences

思路:
由於位置可以變化,所以不需要關心具體的數是多少,只需要知道二進位制表示中的1的個數是多少就可以了。
然後對於一段數,把1的個數加起來,如果是偶數,就說明異或後可以為0,否則就不能。
最後還要滿足最長的數的兩倍小於整個的總和。

程式碼:

#include<bits/stdc++.h>
using namespace std;

#define maxn 300000
#define ll long long

ll n;
ll a[maxn+5];
ll b[maxn+5];
ll sum[maxn+5];
ll even[maxn+
5],odd[maxn+5]; ll find(ll x) { ll y=0; while(x) { if(x&1) y++; x>>=1; } return y; } void readin() { scanf("%I64d",&n); for(ll i=1;i<=n;i++) { scanf("%I64d",&a[i]); b[i]=find(a[i]); } } int main() { readin(); for(ll i=1;i<=n;i++) { sum[i]=sum[i-1]+b[i];
} for(ll i=1;i<=n;i++) { odd[i]=odd[i-1],even[i]=even[i-1]; if(sum[i]&1) odd[i]++; else even[i]++; } ll ans=0; for(ll i=1;i<=n;i++) { if(sum[i-1]&1) ans+=odd[n]-odd[i-1]; else ans+=even[n]-even[i-1]; } for(ll i=1;i<=n;i++) { ll m=min(n,i+64); ll maxb=b[i],
s=0; for(ll j=i;j<=m;j++) { maxb=max(maxb,b[j]); s+=b[j]; if(2*maxb>s&&(s&1)==0) ans--; } } printf("%I64d",ans); return 0; }