0
点赞
收藏
分享

微信扫一扫

HDU - 5536 Chip Factory 字典树的删除


Chip Factory

Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 6090    Accepted Submission(s): 2745


 

Problem Description

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:

maxi,j,k(si+sj)⊕sk

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?

 

 

Input

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≤si≤109
There are at most 10 testcases with n>100

 

 

Output

For each test case, please output an integer indicating the checksum number in a line.

 

 

Sample Input

2 3 1 2 3 3 100 200 300

 

 

Sample Output

6 400

 

 

Source

​​2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)​​

 

 

Recommend

hujie

题意:n个数,求任取两个数的加和,与剩下的数异或的最大值

分析:

01字典树求异或的最大值,需要删除操作,因为01字典树,我们可以对每一个节点进行标记,num[u]表示插入字符的01串经过该节点的次数,删除的时候,遍历数字二进制所对应的节点01,使其num【u】-1就可以了。(其实num跟统计前缀差不多作用)

 

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1005;
const int maxnode=1000000+100;
int num[maxnode];
const int sigma_size=3;
struct Trie
{
int ch[maxnode][sigma_size];
int sz;
void init()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
void insert(ll x)
{
int u=0;
for(int i=32;i>=0;i--)
{
int id=(x>>i)&1;//取出x二进制第i位
if(ch[u][id]==0)
{
ch[u][id]=sz;

memset(ch[sz],0,sizeof(ch[sz]));
num[sz]=0;
sz++;
}
u=ch[u][id];
num[u]++;

}

}
void update(ll x, int d)
{
int u = 0;
for(int i =32; i >= 0; i--){
int index = (x>>i)&1;
u = ch[u][index];
num[u]+=d;
}
}
ll find(ll x)
{
ll ans=0;
int u=0;
for(int i=32;i>=0;i--)
{
int id=(x>>i)&1;
int y=id^1; //找与id不同的
if(ch[u][y]&&num[ch[u][y]])
{
u=ch[u][y];
ans=ans<<1|1; //不同为1,ans=ans*2+1
}
else
{
u=ch[u][id];
ans<<=1; //相同为0,ans=ans*2

}
}
return ans;
}
};
Trie trie;
ll a[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll maxx=0;
int n;
trie.init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
trie.insert(a[i]);
}
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
{
trie.update(a[i],-1);
trie.update(a[j],-1);
maxx=max(maxx,trie.find(a[i]+a[j]));
trie.update(a[i],1);
trie.update(a[j],1);
}

cout<<maxx<<endl;
}

return 0;
}

 

 

举报

相关推荐

0 条评论