Codeforces Round #512(Technocup 2019 Elimination Round 1) E. Vasya and Good Seque (Codeforces 1030E)
阿新 • • 發佈:2018-12-24
題目: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;
}