字典樹處理《異或》

2021-07-16 12:49:42 字數 1239 閱讀 5903

題目:

問題很簡單,現在有乙個陣列a1,a2,a3……an。你的任務就是找到乙個連續子段[l,r],使得al^al+1^……^ar達到最大。

input

多組輸入,每組有兩行。第一行有乙個整數n(1<=n<=10^5),表示陣列的元素個數。第二行有n個元素,依次表示陣列的元素。(0<=ai<=10^6)

output

每組輸出一行,這行僅乙個數字。表示最大的連續子段異或值。

sample input

raw

5 1 2 3 4 5

5 2 3 2 3

初次接觸字典樹,看了很多大神的**,因為我根本不知道為什麼字典樹可以處理異或,現在有了一點點理解所以寫一下部落格強化一下記憶。

題目分析

首先要明白異或是什麼,異或就是相對於二進位制的一種運算,相同為0,不同為1;

對於這道題我們先處理乙個字首,即1~2,1~3,~~~~,1~n,的異或值;對於l~~r區間的異或值就為1~~r的異或值在異或1~~l-1的異或值;現在這個問題就變成了在字首陣列裡找兩個數求他們異或值得 最大;

因為每一位只有0,1,兩種狀態,所以就像乙個二叉,我們題目的資料範圍為10^4所以25位就可以了,我們先建立乙個字典樹,當我們對字典樹進行訪問時就對答案進行比較看誰最大,我們從最高位進行判斷,如果最高位有不同(相同1,不同0)的那麼這個答案肯定是最優的,我們再進行判斷下一位,如果最高位相同我們就直接判斷下一位,又看看下一位是否相同,或者不同,下面**判斷相同不同我用的bool型別如果有不同的話,我肯定是建立了節點的 如果相同就找不到!k這個節點。

廢話多都說了,上碼。

ac**

#include 

#include

#include

using

namespace

std;

int a[100005];

int tree[1000005][2];

int clk=0;

void add(int qq)

}int que(int qq)

return an;

}int main ()

add(0);

for (i=0;iint maxn=que(a[i]);

ans=max(ans,maxn);

}printf ("%d\n",ans);

}return

0;}

POJ 3764 (異或 字典樹)

早就聽過用字典樹求異或最大值,然而沒做過。發現一碰到異或的題就gg,而且因為以前做過的一道類似的題 事實上並不類似 限制了思路,蠢啊 題意 一棵帶權的樹,求任意兩點間路徑異或的最大值。題解 設xor a,b 是求a,b間路徑的異或值,那麼xor a,b xor root,a xor root,b 因...

nefu1248智力異或 字典樹

problem 1248 time limit 2000ms memory limit 65535k 有乙個數列包含n個正整數a 1 a n 1 n 1e5,0 a i 1e9 現在有q次操作 q 1e5 每次操作是以下兩種操作中的一種 1 輸入x,對這n個數分別異或x 2 輸入x,求數列中的某個數...

奶牛異或(01字典樹)

題意 讓你找乙個連續區間異或和最大,如果有相同的,則輸出斷點較小的。題解 01字典樹,利用字首和的思想進行求解,我們在插入字首的同時,也在不斷的更新最大值。我們查詢當前 二進位制字串與已經插入的 二進位制字串中的哪乙個異或和最大?找到最大的那個,讀取這個字首和是到誰結束的,來判斷是否要更新 keep...