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<<"\n"; //建立的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\n";
54         for(int i=1; i<=n; i++) {
55             ans=max(ans,Query(a[i]));
56         }
57         //    cout<<"YES2\n";
58         printf("%I64d\n",ans);
59     }
60     return 0;
61 }


这是指针的写法,感觉复杂度和上面的没啥区别,为啥就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<<"\n"; //建立的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<<"\n"<<"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\n";
63         for(int i=0; i<n; i++) {
64             ans=max(ans,Query(a[i]));
65         }
66     //    cout<<"YES2\n";
67         printf("%I64d\n",ans);
68     }
69     return 0;
70 }

 
时间: 2024-08-05 11:12:10

ACM: Find MaxXorSum 解题报告-字典树的相关文章

ACM:统计难题 解题报告-字典树(Trie树)

统计难题 Time Limit:2000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignati

hdu acm 2844 Coins 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2844 题目意思:有A1,A2,...,An 这 n 种面值的钱,分别对应的数量是C1,C2,...,Cn.问根据这么多数量的钱 能组成多少个 <= m 的钱. 如果用多重背包来做,超时了...如果用记忆化搜索,还是...超时= =..... 这个方法是网上搜的,觉得好神奇,能看懂一些. 它是根据完全背包的思路做的,但是需要限制每种币种的使用数量,于是就多了个used[] 数组来记录了. ! f[j]

hdu acm 1114 Piggy-Bank 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114 题目意思:给出一个空的猪仔钱ang 的重量E,和一个装满钱的猪仔钱ang 的重量F你,实质上能装入得钱的重量就是F - E.接着有n 种币种,每个币种有两个属性刻画:面值 + 重量.问恰好装满(注意关键词: 恰好)后,需要的钱的最少数量所对应的钱是多少(有点拗口= =.)拿第一组数据来说, 10 110 2 1 1 30 50 我们当然是用两张30 来填满这个只能装100重量的罐啦,如果都用面

ACM: Just a Hook 解题报告 -线段树

E - Just a Hook Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive met

ACM: Billboard 解题报告-线段树

Billboard Time Limit:8000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w.所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等.. 在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去. 每张广告都是高度为1宽度为wi的细长的矩形纸条. 贴广告的人总是会优先选择最上面的位置来帖,而且在所有

ACM Minimum Inversion Number 解题报告 -线段树

C - Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

ACM: Hotel 解题报告 - 线段树-区间合并

Hotel Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever th

ACM: 敌兵布阵 解题报告 -线段树

敌兵布阵 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Lily 特别喜欢养花,但是由于她的花特别多,所以照料这些花就变得不太容易.她把她的花依次排成一行,每盆花都有一个美观值.如果Lily把某盆花照料的好的话,这盆花的美观值就会上升,如果照料的不好的话,这盆花的美观值就会下降.有时,Lily想知道某段连续的花的美观值之和是多少,但是,Lily的算术不是很好,你能快

ACM: I Hate It 解题报告 - 线段树

I Hate It Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多组测试,请处理到文件结束. 在每个测