1. 程式人生 > >求n個數中兩數異或的最大值(字母樹)

求n個數中兩數異或的最大值(字母樹)

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#define INF 0x3f3f3f3f3f3f3f
using namespace std;
const int MAXN = 2e5 + 10;

int node;
int next[MAXN][2];
int ed[MAXN];
void add(int cur, int k)
{
    memset(next[node], 0, sizeof(next[node]));
    next[cur][k] = node++;
    //cout << "~~" << node << " ";
}

int cal(int x)
{
    int cur = 0;
    for (int i = 30; i >= 0; --i) {
        int k = (x >> i) & 1;
        if (next[cur][1-k]) cur = next[cur][1-k];
        else cur = next[cur][k];
    }
    //cout << x << " " << ed[cur] << endl;
    return (x ^ ed[cur]);
}

int main()
{
    int n;
    cin >> n;
    int a[MAXN];
    node = 1;
    next[0][0] = next[0][1] = 0;
    memset(ed, 0, sizeof(ed));
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
        int cur = 0;
        for (int j = 30; j >= 0; --j) {
            int k = (a[i] >> j) & 1;
            if (next[cur][k] == 0) add(cur, k);
            cur = next[cur][k];
        }
        ed[cur] = a[i];
    }
    int ans = 0;
    for (int i = 0; i < n; ++i)
        ans = max(ans, cal(a[i]));
    cout << ans << endl;


    int ans2 = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            ans2 = max(ans2, a[i] ^ a[j]);
        }
    }
    cout << ans2 << endl;

    return 0;
}


相關推薦

n個數字母

#include <stdio.h> #include <string.h> #include <math.h> #include <iostream> #include <string> #include <

堆&&堆排序&&N個數找出K個&&優先順序佇列

學習二叉樹後,有一個東西需要我們來關注下,就是堆,對於堆,來說我們可以把堆看作一顆完全二叉樹。這裡我們也可以叫做二叉堆。 二叉堆滿足二個特性: 1.父結點的鍵值總是大於或等於(小於或等於)任何一個子節點的鍵值。 2.每個結點的左子樹和右子樹都是一個二叉堆(

01字典

#include<bits/stdc++.h> using namespace std; const int maxn = 100000 + 5; //集合中的數字個數 typedef long long LL; int ch[32 * maxn

[二進制trie][貪心]CSUOJ1216

include 貪心 targe printf IV 左右 class using ace 題目傳送門 過了好久,終於重新開始寫博客了。。。 這是一道二進制trie樹的模板題。 二進制trie樹,理解一下就是一顆二叉樹,左右兒子為0或1。 然後每插入一個數就進行一次

pre tmp 數字 markdown %d getchar using 整數 getch 1、1216: 異或最大值 http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1216 Time Limit: 2 Sec Me

中國石油大學 Chip Factory(字典處理)

9264: Chip Factory 時間限制: 5 Sec  記憶體限制: 128 MB 提交: 268  解決: 61 [提交] [狀態] [討論版] [命題人:admin] 題目描述 John is a manager of a CPU chip factory,

01字典專題 解決問題不斷更新ing~

以前一直以為字典樹沒有多少用,但是最近一直碰到(難道是以前刷題太少的原因麼),其中有一類問題叫做01字典樹問題,它是用來解決xor的有力武器,通常是給你一個數組,問你一段連續的異或和最大是多少,正常思路貪心dp啥的都會一頭霧水,但是用01字典樹就能很快的解決,實現起來也十分

中國石油大學 Chip Factory(字典處理)

9264: Chip Factory 時間限制: 5 Sec  記憶體限制: 128 MB 提交: 268  解決: 61 [提交] [狀態] [討論版] [命題人:admin] 題目描述 John is a

[cqbzoj]區間

奶牛異或 時間限制: 1 Sec 記憶體限制: 64 MB 題目描述 農民約翰在餵奶牛的時候被另一個問題卡住了。他的所有N(1 <= N <= 100,000)個奶牛在他面前排成一行(按序號1..N的順序),按照它們的社會等級排序。奶牛#

CSU_1216

題目簡述: 經典題目,求一個數組中兩個數異或運算的最大值。題目極其簡單,但是要求的複雜度需要達到O(N * log(N)),還是比較難的。 解題思路: 總的思路就是構建一棵0-1字典樹,然後一個數讓查詢一個與其異或結果最大的數的效率達到O(log(N)

二進位制trie問題

trie樹一般可以用於查詢與指定值最近的,而二進位制trie樹因為每個節點最多有兩個子節點,所以也可以查詢與指定值最遠的值,即異或最大值。 (1)問題:給定一個數組,在陣列中找到兩個數,使得這兩個數的異或值最大 (2)要點:對於陣列中的每個元素,二進位制trie樹查詢異

Codeforces 811C Vladik and Memorable Trip (區間)【線性DP】

所有 一個 true sin %d 如果 不同 esp ace <題目鏈接> 題目大意: 給你n個數,現在讓你選一些區間出來,對於每個區間中的每一種數,全部都只能出現在這個區間。 每個區間的價值為該區間不同的數的異或值之和,現在問你這n個數最大的價值是多少。

6-5 自定型別元素的10 分

6-5 求自定型別元素的最大值(10 分)本題要求實現一個函式,求N個集合元素S[]中的最大值,其中集合元素的型別為自定義的ElementType。函式介面定義:ElementType Max( ElementType S[], int N ); 其中給定集合元素存放在陣列S

mybatis。插入語句如何插入資料庫某一欄位純sql實現

<insert id="inserts"> <selectKey keyProperty="ID" ORDER="BEFORE" resultType="java.lang.I

陣列的連續子陣列之和的一維二維

求陣列的連續子陣列之和的最大值 輸入一個N個元素的整型陣列,數組裡有正數也有負數。陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。求所有子陣列的和的最大值。 例如輸入的陣列為-9  -3  -2  2  -1  2  5  -7  1  5,和最大的子陣列為

hdu 3915 Game N個數取若干個數字使得它們的為0的方法 高斯消元(mod2)

Problem Description   Mr.Frost is a child who is too simple, sometimes naive, always plays some simple but interesting games with his fri

分治演算法N個數第K小()的

這個學期開演算法課,跟著進度寫寫程式碼就好。這周講分治,說到了求N個數中第K小(大)數的問題,寫寫看。 分治演算法的複雜度是O(n),用到了快速排序的思路:先選取一個參考數進行一次快排,拿升序來說的話,快排之後左邊所有數<參考數,右邊所有數>參考數,然後根據左右

O(n)個數連續區間和的

return 區間 scan CI spa 最大 %d 區間和 數組 int n, a[5000]; int main(){ scanf("%d", &n); for (int i = 1; i <= n; i++)cin >>

acm-1003 個數連續區間和的問題

時間複雜度為n的方法: import java.util.Scanner; class Main { public static void main(String[] args) { Scanner sc = new Scanne

個數用函式指標變數呼叫函式

#include<stdio.h> int max(int a,int b) {  if(a>b)  return a;  else  return b; } int main() {     int x,y,z;     scanf("%d%d",&