zoukankan      html  css  js  c++  java
  • *hdu 5536(字典树的运用)


    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


    题意:求下面这个公式的最大值:
    maxi,j,k(si+sj)sk

    思路:如果用普通方法你要分别枚举3个数,n^3感觉会超时的。

    然而完全莫有想到能用字典树,你先把所有的数保存下来,然后删去要用的i和j,再在里面找出能和a[i]+a[j]异或

    出的最大值。相当于值需要枚举i和j即可。          /*好机智


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <functional>
    typedef long long ll;
    using namespace std;
    
    int a[1005];
    
    struct node
    {
        int number;
        int flag;
        int next[2];
        void ini()
        {
            next[0] = next[1] = 0;
            flag = 0;
        }
    } pnode[1000005];
    int root = 0;
    int tot;
    
    void inser(int x)
    {
        int tt = root;
        for(int i = 30; i >= 0; i --)
        {
            int t;
            if(x & (1<<i))t = 1;
            else  t = 0;
            if(!pnode[tt].next[t])
            {
                pnode[tt].next[t] = ++tot;
                pnode[tot].number = t;
            }
            tt = pnode[tt].next[t];
            pnode[tt].flag++;
        }
    }
    
    void delet(int x)
    {
        int tt = root;
        for(int i = 30; i >= 0; i--)
        {
            int t;
            if(x & (1<<i))t = 1;
            else  t = 0;
            tt = pnode[tt].next[t];
            pnode[tt].flag --;
        }
    }
    
    int query(int x)
    {
        int tt = root;
        for(int i = 30; i >= 0; i--)
        {
            int t;
            if(x & (1<<i)) t = 1;
            else t = 0;
            if(t == 1)
            {
                int nex = pnode[tt].next[0];
                if(pnode[nex].flag > 0 && nex) tt = pnode[tt].next[0];
                else
                {
                    tt = pnode[tt].next[1];
                    x ^= (1<<i);
                }
            }
            else
            {
                int nex = pnode[tt].next[1];
                if(pnode[nex].flag > 0 && nex)
                {
                    tt = pnode[tt].next[1];
                    x ^= (1<<i);
                }
                else tt = pnode[tt].next[0];
            }
        }
        return x;
    }
    
    int main()
    {
        int T,n;
        scanf("%d",&T);
        while(T--)
        {
            int ans = 0;
            scanf("%d",&n);
            tot = 0;
            for(int i = 0; i < n; i++)   scanf("%d",a+i);
            for(int i = 0; i < n; i++)   inser(a[i]);
    
            for(int i = 0; i < n; i++)
            {
                delet(a[i]);
                for(int j = i+1; j < n; j++)
                {
                    delet(a[j]);
                    ans = max(ans,query(a[i] + a[j]));
                    inser(a[j]);
                }
                inser(a[i]);
            }
            for(int i = 0;i < tot;i++)
            {
                pnode[i].ini();
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    一元运算符重载 前置和后置++ --(这种一般用成员函数来实现重载)
    运算符中的二元重载,为什么要调用友元函数而不是全局函数的问题
    关于数组的封装不知道为什么错了,具体代码如下
    关于对象的动态建立和释放
    关于构造函数中调用构造函数的危险
    关于析构函数,构造函数匿名对象的总结,以厚忘了,可以回来观看很全
    关于深拷贝和浅拷贝的疑问
    构造函数的调用大全
    构造函数的调用(其中不包括赋值构造函数)
    LeetCode:Add Digits
  • 原文地址:https://www.cnblogs.com/Przz/p/5409689.html
Copyright © 2011-2022 走看看