【hdu 5536】【 2015ACM/ICPC亚洲区长春站 】Chip Factory 题意&题解&代码

题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5536
题意:
给定n个个数s1, s2… sn,求最大的(si+sj)^sk且满足(i!=j!=k)。
题解:
很明显的一道字典树题目,把每个数都插入字典树,枚举两个数的和。考虑到可能会有重复的数,每次枚举到i,j时首先在字典树上删除 si 和 sj 然后再查询 si+sj 。
代码:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,m,tot,T,cnt[70005];
int tr[70005][2],s[1005];
void init(int i)
{
    tr[i][1]=tr[i][0]=0;
    cnt[i]=0;
}
void add(int x,int id)
{
    int now=0;
    for (int i=31;i>=0;i--)
    {
        int p=0;
        if (((1<<i)&x)!=0) p=1;
        if (!tr[now][p]) 
        {
            tot++;
            tr[now][p]=tot;
            init(tot);
        }
        now=tr[now][p];
        cnt[now]+=id;
    }
}
int query(int x)
{
    int now=0;
    int tmp=0;
    for (int i=31;i>=0;i--)
    {
        int p=1;
        if (((1<<i)&x)!=0) p=0;
        if (!tr[now][p] || cnt[tr[now][p]]<=0) now=tr[now][!p];
        else tmp+=(1<<i),now=tr[now][p];
    }
    return tmp;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        tot=0;
        init(tot);      
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&s[i]);
            add(s[i],1);        
        }       
        int ans=-1;
        for (int i=1;i<=n;i++)
        for (int j=i+1;j<=n;j++)
        {
            add(s[i],-1);
            add(s[j],-1);
            ans=max(ans,query(s[i]+s[j]));
            add(s[i],1);
            add(s[j],1);    
        }
        memset(cnt,0,sizeof(cnt));
        printf("%d\n",ans);
    }
}

你可能感兴趣的:(字典树,2015ACM)