UPC-9264 Chip Factory(01字典樹)
題目描述 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:
輸入 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
題意: 給序列A,找到i,j,k使得序列中(Ai+Aj)^Ak最大。i≠j≠k 題解: 關於異或值最大的問題容易想到01字典樹,問題在於三種數不能重複用,那麼兩層for暴力列舉Ai+Aj,使其異或01字典樹上的Ak,記錄一個最大值即可,不能重複用的情況,每次列舉到第i個和第j個值時,在字典樹上刪除這兩個值,那麼k就不會查詢到和兩者相同的位置了。刪除後注意要加回字典樹上
#include<bits/stdc++.h>
#define LL long long
#define M(a,b) memset(a,b,sizeof a)
#define pb(x) push_back(x)
using namespace std;
const int maxn=1e3+7;
int tre[maxn<<5][2];
int cnt[maxn<<5];
int tot;
void insert(LL a,int rt,int add)
{
for(int i=31; i>=0; i--)
{
int x=(a>>i)&1;
if(!tre[rt][x])
{
tre[rt][x]=++tot;
M(tre[tre[rt][x]],0);
}
rt=tre[rt][x];
cnt[rt]+=add;
}
}
LL finds(LL a,int rt)
{
LL ans=0;
for(int i=31;i>=0;i--)
{
ans<<=1;
int x=(a>>i)&1;
if(tre[rt][!x]&&cnt[tre[rt][!x]])rt=tre[rt][!x],ans|=1;
else rt=tre[rt][x];
}
return ans;
}
int t,n;
LL a[1080];
int main()
{
scanf("%d",&t);
while(t--)
{
LL ans=0;
tot=0;
int rt=++tot;
M(tre[rt],0);
M(cnt,0);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
insert(a[i],rt,1);
}
for(int i=1;i<n;i++)
{
insert(a[i],rt,-1);
for(int j=i+1;j<=n;j++)
{
insert(a[j],rt,-1);
ans=max(ans,finds(a[i]+a[j],rt));
insert(a[j],rt,1);
}
insert(a[i],rt,1);
}
printf("%lld\n",ans);
}
}