hdu5536 Chip Factory

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.

1T1000
3n1000
0si109
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
 
题意:给你n个数,让你找出3个不同下标对应的数,使得(s[i]+s[j])^s[k]的值最大。
思路:我们可以建一棵trie树,先把n个数都插入,然后枚举n*n个(i,j),先把trie树上的s[i],s[j]先消去,然后在树上找到异或和最大的k。我们每个节点记录一个val值。
插入时对所有经过节点的val值加1,删除就将对应节点的val值减1。在树上匹配的时候就只走那些val值为正的节点。匹配的过程中,首先看树中最高位能否异或得到1。
能的话就往能的那个方向走,否则往另外一个方向走。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
#define maxnode 100000
#define maxn 1005
int a[maxn];
int sz,tot;
int ch[maxnode][2];
int val[maxnode];
char d[maxn][40];

void init(){
    sz=0;
    memset(ch,0,sizeof(ch));
    memset(val,0,sizeof(val));
}
int idx(char c){
    return c-'0';
}

void update(char *s,int num){
    int i,u=0,j;
    int len=strlen(s);
    char s1[40];
    for(i=0;i<len;i++){
        int c=idx(s[i]);
        if(!ch[u][c]){
            sz++;
            val[sz]+=num;
            ch[u][c]=sz;
            u=sz;
        }
        else{
            u=ch[u][c];
            val[u]+=num;
        }
    }
}

int b[40],cnt;
int chazhao(char *s){
    int i,j,u=0;
    int len=strlen(s);
    int num=0;
    for(i=0;i<len;i++){
        int c=idx(s[i]);
        if(val[ch[u][1^c ] ]){
            b[i]=1;
            u=ch[u][1^c ];
        }
        else{
            b[i]=0;
            u=ch[u][c];
        }
        num=num*2+b[i];
    }
    return num;
}





int main()
{
    int n,m,i,j,T,t,k;
    char s[40];
    scanf("%d",&T);
    while(T--)
    {
        init();
        memset(s,0,sizeof(s));
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            t=a[i];
            int tot=0;
            while(t){
                s[tot++]=t%2+'0';
                t>>=1;
            }
            while(tot<35){
                s[tot++]='0';
            }
            s[tot]='\0';
            reverse(s,s+tot);
            update(s,1);
            strcpy(d[i],s);
        }
        int ans=0;
        for(i=1;i<n;i++){
            update(d[i],-1);
            for(j=i+1;j<=n;j++){
                int num=a[i]+a[j];
                update(d[j],-1);

                tot=0;
                char str[40];
                while(num){
                    str[tot++]=num%2+'0';
                    num>>=1;
                }
                while(tot<35){
                    str[tot++]='0';
                }
                str[tot]='\0';
                reverse(str,str+tot);
                cnt=0;
                int temp=chazhao(str);
                ans=max(ans,temp);
                update(d[j],1);
            }
            update(d[i],1);
        }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(Trie树)