Chip Factory(0 1字典樹 刪除)
時間限制: 5 Sec 記憶體限制: 128 MB 提交: 260 解決: 57 [提交] [狀態] [討論版] [命題人:admin]
題目描述
John is a manager of a CPU chip factory, the factory produces lots of chips everyday. To manage large amounts of products, every processor has a serial number. More specifically, the factory produces n chips today, the i-th chip produced this day has a serial number si. At the end of the day, he packages all the chips produced this day, and send it to wholesalers. More specially, he writes a checksum number on the package, this checksum is defined as below:
which i, j, k are three different integers between 1 and n. And is symbol of bitwise XOR.
Can you help John calculate the checksum number of today?
輸入
The first line of input contains an integer T indicating the total number of test cases. The first line of each test case is an integer n, indicating the number of chips produced today. The next line has n integers s1 , s2 ,..., sn , separated with single space, indicating serial number of each chip.
- 1≤T≤1000
- 3≤n≤1000
- 0≤s i≤109
- There are at most 10 testcases with n > 100
輸出
For each test case, please output an integer indicating the checksum number in a line.
樣例輸入
2
3
1 2 3
3
100 200 300
樣例輸出
6
400
題目大意:
給 N 個數,在這 N 個數裡找到三個值 i, j,k 使得(i+j)⊕ k 最大,輸出這個最大值。
解題思路:
每次在01字典樹裡刪除 i 和 j 然後 (i+j)和01字典樹裡的匹配求最大異或值。
#include <bits/stdc++.h>
#define ll long long int
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 1e3+10;
int ch[MAXN*32][2];
ll value[MAXN*32];
ll b[MAXN];
int num[MAXN*32];
int node_cnt;
void init()
{
memset(ch[0], 0, sizeof(ch[0]));
node_cnt = 1;
}
void Insert(ll x)
{
int cur = 0;
for(int i = 32; i >= 0; i--){
int index = (x>>i)&1;
if(!ch[cur][index]){
memset(ch[node_cnt], 0, sizeof(ch[node_cnt]));
ch[cur][index] = node_cnt;
value[node_cnt] = 0;
num[node_cnt++] = 0;
}
cur = ch[cur][index];
num[cur]++;
}
value[cur] = x;
}
void update(ll x, int d)
{
int cur = 0;
for(int i =32; i >= 0; i--){
int index = (x>>i)&1;
cur = ch[cur][index];
num[cur]+=d;
}
}
ll query(ll x)
{
int cur = 0;
for(int i = 32; i >= 0; i--)
{
int index = (x>>i)&1;
if(ch[cur][index^1] && num[ch[cur][index^1]]) cur = ch[cur][index^1];
else cur = ch[cur][index];
}
return x^value[cur];
}
int main()
{
int T_case, N;
scanf("%d", &T_case);
while(T_case--)
{
scanf("%d", &N);
init();
for(int i = 1; i <= N; i++)
{
scanf("%lld", &b[i]);
Insert(b[i]);
}
ll ans = 0;
for(int i = 1; i <= N; i++){
for(int j = 1; j <= N; j++){
if(i == j) continue;
update(b[i], -1);
update(b[j], -1);
ans = max(ans, query(b[i]+b[j]));
update(b[i], 1);
update(b[j], 1);
}
}
printf("%lld\n", ans);
}
return 0;
}