zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
    }
    
    
  • 相关阅读:
    兄弟连,一般人来不起,来的肯定不是一般人!
    50天之脱变,66期第一个项目感受。切记平常心
    2016十大影响事件
    为什么要写年终总结
    20161228阅读笔记
    为什么要认识牛人
    李笑来:演讲能力是我这一生有幸学到的最重要能力
    张辉:工作几年就应该给自己“清零”
    小马宋:目标决定方法~坚持目标而不是方法
    李笑来的财务自由法~把一份时间卖出很多份
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135694.html
Copyright © 2011-2022 走看看