Untitled

mail@pastecode.io avatar
unknown
plain_text
5 months ago
2.3 kB
4
Indexable
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

void init()
{
	cin.tie(0);
	cin.sync_with_stdio(0);
}

const int MAX_CHAR = 2, max_bits = 21;

struct Trie
{
	Trie *child[MAX_CHAR];
	int fre[2];

	Trie()
	{
		memset(child, 0, sizeof(child));
		memset(fre, 0, sizeof(fre));
	}

	void insert(int i, int &x)
	{
		if (i < 0)
			return;

		bool cur = (x & (1 << i));
		fre[cur]++;

		if (child[cur] == 0)
			child[cur] = new Trie();
		child[cur]->insert(i - 1, x);
	}

	void query(int i, int &x, int &max_, long long &ans)
	{
		if (i < 0)
			return;

		bool cur = (x & (1 << i));
		bool cur_max = (max_ & (1 << i));

		if (cur_max == 0)
			ans += fre[!cur];

		cur = cur ^ cur_max;
		if (child[cur] == 0)
			return;

		child[cur]->query(i - 1, x, max_, ans);
	}

	void dele(int i)
	{
		if (i < 0)
			return;

		if (child[0] != 0)
		{
			child[0]->dele(i - 1);
			delete child[0];
		}

		if (child[1] != 0)
		{
			child[1]->dele(i - 1);
			delete child[1];
		}
	}
};

long long ans = 0;
void solve(int l, int r, vector<int> &v)
{
	if (l >= r)
		return;

	int mid = (l + r) >> 1;

	solve(l, mid, v);
	solve(mid + 1, r, v);

	int max_r = 0, max_l = 0;
	long long fre = 0;

	Trie left, right;

	int j = mid;
	for (int i = mid; i >= l; i--)
	{
		max_r = max(max_r, v[i]);

		while (j + 1 <= r && max(max_l, v[j + 1]) <= max_r)
		{
			j++;
			max_l = max(max_l, v[j]);

			fre = 0;
			right.query(max_bits, v[j], max_l, fre);
			ans += fre * max_l;

			left.insert(max_bits, v[j]);
		}

		fre = 0;
		left.query(max_bits, v[i], max_r, fre);
		ans += fre * max_r;

		right.insert(max_bits, v[i]);
	}

	while (j + 1 <= r)
	{
		j++;
		max_l = max(max_l, v[j]);

		fre = 0;
		right.query(max_bits, v[j], max_l, fre);
		ans += fre * max_l;
	}

	left.dele(max_bits);
	right.dele(max_bits);
}

int main()
{
	init();
	// freopen("mootube.in", "r", stdin);
	// freopen("mootube.out", "w", stdout);
	int t;
	cin >> t;

	while (t--)
	{
		int n;
		cin >> n;

		vector<int> v(n);
		for (int i = 0; i < n; i++)
			cin >> v[i];

		ans = 0;
		solve(0, n - 1, v);
		cout << ans << "\n";
	}

	return 0;
}
Leave a Comment