hdu 5536 Chip Factory 字典树

来源:互联网 发布:李拉大提琴知乎 编辑:程序博客网 时间:2024/05/24 03:15

Chip Factory

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


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
231 2 33100 200 300
 

Sample Output
6400
 

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

Recommend
hujie   |   We have carefully selected several similar problems for you:  5551 5550 5549 5548 5547 




解题报告:
1T1000
3n1000
0si109
There are at most 10 testcases with n>100
题意:输入n个数,求最大的(a+b)^c。(a、b、c要互不相同。)
建立字典树,把一个int型的数存放到字典树,里面每个结点有两条路径,nex[0]和nex[1],代表这个结点的下一个节点是0还是1,并且有一个cnt表示有多少个数 在该位置(位运算,该结点表示的位置)是0或1(和该结点表示的数字 相同)。
字典树深度较小的点,表示的位数越高。

由于n最多有1000个,字典树的深度是32,那么数组大小超过1000*32即可。

for两重循环,表示a和b,如果a和b序号相同,则跳过。
然后在字典树里面,把a和b经过的每个结点的cnt--。(就是在字典树里拆掉a和b。)
然后遍历字典树,找到最优解:如果在树的某一层上,(a+b)在该位是1,那么找这一层有没有0的,若是0,则找1(贪心)。


#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<climits>#include<queue>#include<vector>#include<map>#include<sstream>#include<set>#include<stack>#include<cctype>#include<utility>#pragma comment(linker, "/STACK:102400000,102400000")#define PI 3.1415926535897932384626#define eps 1e-10#define sqr(x) ((x)*(x))#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)#define  lson   num<<1,le,mid#define rson    num<<1|1,mid+1,ri#define MID   int mid=(le+ri)>>1#define zero(x)((x>0? x:-x)<1e-15)#define mk    make_pair#define _f     first#define _s     secondusing namespace std;//const int INF=    ;typedef long long ll;//const ll inf =1000000000000000;//1e15;//ifstream fin("input.txt");//ofstream fout("output.txt");//fin.close();//fout.close();//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);const int INF =0x3f3f3f3f;const int maxn=1010    ;//const int maxm=    ;int n,root,cnt,a[maxn];struct Node{    int num;    int nex[2];     Node()    {        num=nex[1]=nex[0]=0;//严重错误:num=nex[1]=nex[2]=0;    };} node[maxn*33];int newNode(){    node[++cnt]= Node();    return cnt;}void build(int x){    int s=root, y;    for(int i=30;i>=0;i--)    {        if(x&(1<<i))  y=1;        else y=0;        /*这个是极端错误的写法!!!: int y= (x&(1<<i) );*/        Node & now=node[s];        if(now.nex[y]==0)  now.nex[y]=newNode();        s=now.nex[y];        node[s].num++;    }}void delet(int x){    int s=root,y;    for(int i=30;i>=0;i--)    {        if(x&(1<<i))  y=1;        else y=0;        Node & now=node[s];        s=now.nex[y];        node[s].num--;    }}int query(int x){    int s=root,y;    for(int i=30;i>=0;i--)    {        if(x&(1<<i))  y=1;        else y=0;        Node &now=node[s];        int ne=y;        //下面的if else 原来出错严重,在于ne的取值        if(y)        {            if(now.nex[0]&&  node[now.nex[0]].num)  ne=0  ;            else    x^=  ( 1<<i) ;        }        else        {            if(now.nex[1]&& node[now.nex[1]].num)  x^=  (1<<i)  ,ne=1 ;            else     ;        }        s=now.nex[ne];    }    return x;}int main(){    int T;    scanf("%d",&T);    while(T--)    {       scanf("%d",&n);       cnt=0;       root=newNode();       for(int i=1;i<=n;i++)  scanf("%d",&a[i]),build(a[i]);       int maxi=0;       for(int i=1;i<=n;i++)       {           delet(a[i]);           for(int j=1;j<=n;j++)           {               if(j==i)  continue;               delet(a[j]);               maxi=max(maxi,query(a[i]+a[j]) );               build(a[j]);           }           build(a[i]);       }       printf("%d\n",maxi);       for(int i=1;i<=cnt;i++)       {           node[i].num=node[i].nex[0]=node[i].nex[1]=0;       }    }    return 0;}



0 0
原创粉丝点击