• ACM: Find MaxXorSum 解题报告-字典树


    Find MaxXorSum
    Time Limit:2000MS     Memory Limit:65535KB     64bit IO Format:
    
    Description
    Given n non-negative integers, you need to find two integers a and b that a xor b is maximum. xor is exclusive-or.
    Input
    Input starts with an integer T(T <= 10) denoting the number of tests. 
    For each test case, the first line contains an integer n(n <= 100000), the next line contains a1, a2, a3, ......, an(0 <= ai <= 1000000000);
    Output
    For each test case, print you answer.
    Sample Input
    2 4 1 2 3 4 3 7 12 5

    Sample Output 7 11

    这个题目其实思路很简单,就我知道的写法有Trie树指针和静态数组两种写法,一开始写的指针用了pow函数TLE了2次,然后换位运算又TLE两次醉了。。
    后面换成静态数组数组开大了RE了一次。。。哭。。。
    这是AC代码:
     1 #include"iostream"
     2 #include"algorithm"
     3 #include"cstdio"
     4 #include"cmath"
     5 #include"cstring"
     6 #define MX 1400000
     7 #define INF 0x3f3f3f3f
     8 #define lson l,m,rt<<1
     9 #define rson m+1,r,rt<<1|1
    10 using namespace std;
    11 int tree[MX][2],xx;
    12 
    13 void BuildTrie(long long a) {
    14     int i=31;
    15     int p=0;
    16     while(0<=i) {
    17         bool num=a&(1<<i);
    18         if(!tree[p][num]) {        //如果节点为空 
    19             tree[p][num]=++xx;//标记并创建新的子节点 
    20         }
    21         p=tree[p][num];
    22         //    cout<<"YES"<<i<<"   B is:"<<num<<"
    "; //建立的Trie树的样子
    23         i--;
    24     }
    25 }
    26 
    27 long long Query(long long  a) {
    28     int i=31,p=0;
    29     long long ans=0;
    30     while(0<=i) {
    31         bool num=!(a&(1<<i));  //取反查找
    32         if(tree[p][num]) p=tree[p][num],ans+=1<<i;//如果和原来的那一为相反的存在的话,返回值就加上,并且在这个支路走
    33         else p = tree[p][!num];  //按照相同的顺序找
    34     //    cout<<"YES"<<i<<"   B is:"<<num<<"     ans is:"<<ans<<endl;   //查询时候的Trie树的样子
    35         i--;
    36     }
    37     return ans;
    38 }
    39 
    40 int main() {
    41     int T,n;
    42     long long a[100050],ans;
    43     scanf("%d",&T);
    44     while(T--) {
    45         ans=0;
    46         memset(tree,0,sizeof(tree));
    47         xx=0;
    48         scanf("%d",&n);
    49         for(int i=1; i<=n; i++) {
    50             scanf("%I64d",&a[i]);
    51             BuildTrie(a[i]);
    52         }
    53         //cout<<"YES1
    ";
    54         for(int i=1; i<=n; i++) {
    55             ans=max(ans,Query(a[i]));
    56         }
    57         //    cout<<"YES2
    ";
    58         printf("%I64d
    ",ans);
    59     }
    60     return 0;
    61 }
    View Code
    
    
    这是指针的写法,感觉复杂度和上面的没啥区别,为啥就TLE了呢? 希望有人知道给我指点下。
     1 #include"iostream"
     2 #include"algorithm"
     3 #include"cstdio"
     4 #include"cmath"
     5 #include"cstring"
     6 #define MX 110000
     7 #define INF 0x3f3f3f3f
     8 #define lson l,m,rt<<1
     9 #define rson m+1,r,rt<<1|1
    10 using namespace std;
    11 
    12 struct Trie {
    13     Trie *next[2];
    14 } root;
    15 
    16 void BuildTrie(int a) {
    17     Trie *p=&root,*q;
    18     int i=31;
    19     while(i>=0) {
    20     bool num=a&(1<<i);
    21         if(p->next[num]==NULL) {
    22             q=(Trie *)malloc(sizeof(root));//申请一块新内存; //动态分配内存
    23             q->next[1]=NULL;
    24             q->next[0]=NULL;    //清空申请内存的所有子节点
    25             p->next[num]=q;        //往子节点下去继续记录字典树
    26             p=p->next[num];
    27         } else {
    28             p=p->next[num];
    29         }
    30     //    cout<<"YES"<<i<<"   B is:"<<num<<"
    "; //建立的Trie树的样子 
    31         i--;
    32     }
    33 }
    34 
    35 long long Query(int a) {
    36     Trie *p=&root;
    37     long long ans=0;
    38     int i=31;
    39     while(0<=i) {
    40         bool num=a&(1<<i);  
    41         if(p->next[!num]!=NULL) p=p->next[!num],ans+=1<<(i);//如果和原来的那一为相反的存在的话,返回值就加上,并且在这个支路走
    42         else if(p->next[num]!=NULL) p=p->next[num];  //按照相同的顺序找
    43     //    cout<<"YES"<<i<<"   B is:"<<num<<"
    "<<"ans is:"<<ans<<endl;   //查询时候的Trie树的样子 
    44         i--;
    45     }
    46     return ans;
    47 }
    48 
    49 int main() {
    50     int T,n,a[MX];
    51     long long ans;
    52     scanf("%d",&T);
    53     while(T--) {
    54         ans=0;
    55         root.next[0]=NULL;
    56         root.next[1]=NULL;
    57         scanf("%d",&n);
    58         for(int i=0; i<n; i++) {
    59             scanf("%d",&a[i]);
    60             BuildTrie(a[i]);
    61         }
    62         //cout<<"YES1
    "; 
    63         for(int i=0; i<n; i++) {
    64             ans=max(ans,Query(a[i]));
    65         }
    66     //    cout<<"YES2
    "; 
    67         printf("%I64d
    ",ans);
    68     }
    69     return 0;
    70 }
    View Code
     
  • 相关阅读:
    回调函数案例(二)
    回调函数案例(一)
    liteos学习文档liteos.github.io
    HeapAlloc、GlobalAlloc和new等内存分配有什么区别么?
    C语言中字符数组和字符串指针分析
    socket 连接,使得地址马上可以重用
    shutdown 和closesocket
    IP地址转换成Long型数字的算法
    WSAStartup( )
    关于完成端口IOCP异步接收连接函数AcceptEx注意事项
  • 原文地址:https://www.cnblogs.com/HDMaxfun/p/5698379.html
Copyright © 2020-2023  润新知