1. 程式人生 > >UPC-9264 Chip Factory(01字典樹)

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: 在這裡插入圖片描述

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

題意: 給序列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);
    }
}