Vasya and Good Sequences CodeForces - 1030E
阿新 • • 發佈:2021-07-09
原題連結
考察:思維
思路:
從樣例一很容易想到二進位制1的個數一定要為偶數個,但是這樣很容易想到反例:1 14,雖然總和也為偶數個但是不成立.這裡就延伸出新的規則:1的個數最多的不超過總和的/2.
總結來說就是:\(sum[r]-sum[l-1]\)為偶,且\(maxn_{l,r}<=\frac{sum}{2}\).
先考慮優化求偶數區間和.我們用\(sum[i][0/1]\)記錄1~i中,sum%2為1,0的個數.那麼我們就可以\(O(n)\)算出只考慮前面條件的答案數.
\(manx<=64\),每個\(a_i\)至少貢獻一個1,所以只需要考慮\((i-128,i]\)
Code
#include <iostream> #include <cstring> using namespace std; typedef long long LL; const int N = 300010; int n,cnt[N],sum[N][2],s[N]; LL a[N],res; LL lowbit(LL x) { return x&-x; } int get(LL x) { int sum = 0; while(x) { sum++; x -= lowbit(x); } return sum; } int main() { scanf("%d", &n); sum[0][0] = 1; for (int i = 1; i <= n;i++) { scanf("%lld", &a[i]); cnt[i] = get(a[i]); s[i] = s[i - 1] + cnt[i]; sum[i][s[i]%2]++; sum[i][0] += sum[i - 1][0]; sum[i][1] += sum[i - 1][1]; res += sum[i - 1][s[i]%2]; } for (int i = 1; i <= n;i++) { int l = max(i - 128, 0), maxn = 0; for (int j = i - 1; j >= l;j--) { maxn = max(cnt[j+1], maxn); if((s[j]-s[i])%2==0&&maxn>(s[i]-s[j])/2) res--; } } printf("%lld\n", res); return 0; }