E. Vasya and Good Sequences

topic

Meaning of the questions:

    Given a set of sequence elements which can be changed to an arbitrary position at which a binary 1. Determined interval [l, r], such that the element interval after the exclusive OR operation value of zero. Such number of output sections.
     1 n 3 1 0 5 1 a i 1 0 18 1≤n≤3⋅10^5,1≤a_i≤10^{18}

analysis:

    For this first issue, usually enumerate the left section, then go to the right section counts.
    Since the number of bits can be placed arbitrarily, so long as we consider each count of the number 1 on it. A section for, when the total number is greater than 1 and up to twice the total number of 1 is an even number that is eligible. Because we can always use a 1 1 that eliminated most of the total number of minus 2, the maximum minus 1, remains twice the state. The even nature is obvious, such as XOR to 1.
    Since the number of a number of at most 1 in 63, so when the total range of more than twice, the first condition necessarily satisfied. So long as we maintain an even number of 1s can be. Note of the current interval [i, j], then we go gauge [j + 1, k] of this section number is the number 1 and the original section add up to an even number of 1, i.e. [j + 1 , n] within this range [j + 1, k] is a number of odd or even number.
    Because the number of 1's are additive, we can first calculate a prefix and v [I] represented by [1, I] the number of the section 1, and then maintaining a suffix and cnt [i] represents a [i, n] of this interval v [ j] is the even number in order to count. So when we want to count [j, k] of a number of intervals, and can be obtained by subtracting the prefix. Since we only focus on its parity, so if v [j] is even, no effects, the number of parity can be interchanged.

#include <iostream>
using namespace std;

typedef long long ll; 

int num[300005],v[300005],cnt[300005];

int count(ll x)
{
	int ans = 0;
	while( x )
	{
		if( x & 1 ) ans ++;
		x >>= 1;
	}
	return ans;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		ll x;
		cin >> x;
		num[i] = count(x);
	}
	for (int i = 1; i <= n; i++)
	{
		v[i] = v[i-1] + num[i];
	}
	for (int i = n; i >= 1; i--)
	{
		cnt[i] = cnt[i+1];
		if( v[i] % 2 == 0 ) cnt[i] ++;
	}
	ll ans = 0;
	for (int i = 1; i <= n; i++)
	{
		int sum = num[i];
		int maxn = num[i];
		for (int j = i + 1; j <= n; j++)
		{
			sum += num[j];
			maxn = max(maxn,num[j]);
			if( sum % 2 == 0 && 2*maxn <= sum ) ans ++;
			if( sum > 128 )
			{
				if( sum % 2 == 0 )
				{
					if( v[j] % 2 == 0 ) ans += cnt[j+1];
					else ans += n - j - cnt[j+1];
				}else
				{
					if( v[j] % 2 == 0 ) ans += n - j - cnt[j+1];
					else ans += cnt[j+1];
				}
				break;
			}
		}
	}
	cout << ans << '\n';
	return 0;
}

Published 132 original articles · won praise 6 · views 7934

Guess you like

Origin blog.csdn.net/weixin_44316314/article/details/104783940