[HDU 5536] 2015 ACM-ICPC Changchun Chip Factory 01 Dictionary Tree

There's an array that lets you select three numbers, so that two of them add up and differ or the other number is the largest.

It is obvious that the dictionary tree of 01 should be used at most. The problem is to select three numbers. We can insert all the numbers into the 01 dictionary tree in advance. When enumerating two of them, we delete the two numbers on the dictionary tree first, and then query them. The problem arises again. How do we delete it? Because we use the public prefix, we can count the edges of the 01 dictionary tree, insert + 1 every time, delete - 1, so that we can complete the deletion operation.

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 7; // Number of Inserted Strings
typedef long long ll;
const ll inf = 1e5;
int ch[maxn * 32][2], sz; // edge
ll val[maxn * 32];  // spot
ll a[maxn], num[maxn * 32]; // num records the number of times each edge is used 
void init() // Initialization
{
	sz = 1;  // Root node
	memset(ch, 0, sizeof(ch));
	memset(num, 0, sizeof(num));
}
void insert(ll x)  // insert
{
	int u = 0;
	for(int i = 32; i >= 0; i--) {
		int v = (x >> i) & 1;
		if(ch[u][v]) num[ch[u][v]] ++; // If you already have side access times + 1
		if(!ch[u][v]) {
			ch[u][v] = sz++;
			num[ch[u][v]] ++;
			val[ch[u][v]] = 0;
		}
		u = ch[u][v];
	}
	val[u] = x;
}
void delete1(ll x)  // delete
{
	int u = 0;
	for(int i = 32; i >= 0; i--) {
		int v = (x >> i) & 1;
		num[ch[u][v]]--;  // Only the number of times you need to walk - 1
		u = ch[u][v];
	}
}
ll query(ll x)  // query
{
	int u = 0;
	for(int i = 32; i >= 0; i--) {
		int v = (x >> i) & 1;
		if(ch[u][v^1] && num[ch[u][v^1]] > 0) u = ch[u][v^1];  // Greedy Choices
		else u = ch[u][v];
	}
	return val[u];
}
int main()
{
	int t, n;
	scanf("%d", &t);
	while(t--) {
		init();
		scanf("%d", &n);
		for(int i = 0; i < n; i++) {
			scanf("%lld", &a[i]);
			insert(a[i]);
		}
		ll maxx = -inf;
		int x, y;
		for(int i = 0; i < n; i++) {
			delete1(a[i]);
			for(int j = i + 1; j < n; j++) {
				delete1(a[j]);
				ll ans = query(a[i] + a[j]);
				if((ans ^ (a[i] + a[j])) > maxx) maxx = (ans ^ (a[i] + a[j]));
				insert(a[j]);
			}
			insert(a[i]);
		}
		printf("%lld\n", maxx);
	}
	return 0;
}

 

Posted by wolfcry044 on Mon, 30 Sep 2019 04:14:41 -0700