1. 程式人生 > >SPOJ MAXOR (分塊 || 可持久化字典樹 || 異或)(好題)

SPOJ MAXOR (分塊 || 可持久化字典樹 || 異或)(好題)

pan log max nta 得到 second 連續 class ...

You are given a sequence A[1], A[2], ..., A[N]. (0 ≤ A[i] < 231, 1 ≤ N ≤ 12000).

A query is defined as follows:

  • Query(x,y) = Max { a[i] xor a[i+1] xor ... xor a[j] ; l ≤ i ≤ j ≤ r }.
  • l = min ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).
  • r = max ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).
  • lastans[1] = 0 , lastans[i] = Query[i-1].

Given M queries, your program must output the results of these queries. (0 ≤ M ≤ 6000).

IMPORTANT : PROBLEM ENHANCED. ( I‘M SO SORRY.. )

Input

  • The first line of the input file contains 2 numbers : N M.
  • In the second line, N numbers follow.
  • M lines follow, where line i contains 2 numbers xi and yi.

Output

Your program should output the results of the M queries, one query per line.

Example

Input:
3 3
1 4 3
0 1
0 1
4 3

Output:
5
7
7

題目:

對於每個詢問,輸出[L,R]區間的最大的連續異或值,強制在線。

解法: 分塊+可持久化字典樹

  1. 首先,分塊,把每個點分屬於一個塊,belong[i]=(i-1)/sqrt(n) +1;
  2. 預處理得到每個塊的右邊界到右邊的每個區間的最大異或,即如果(i-1)%sqrt(n)=0 ,則計算Maxxor[belong[i],j],(i<=j<=n)(這裏很關鍵,不過先別管這裏這麽實現的,看完
  3. 對於每個詢問[L,R],由於我們預處理得到了[belong[L],R]的最大異或和,現在只要計算[t,R]的最大異或和(L<=t<=belong[L]的右邊界)。

-------------------------------------------嗯,看似行得通,怎麽實現呢?----------------------------------------

首先,此題的分塊沒有暴力刪除,沒有添加等等操作,分塊只是為了預處理,的得到多個區間的最大異或和。

對於第二步, 我們怎麽實現呢,看似復雜度很大。但是我們對於MAXOR[i,j],充分利用到前面計算的結果,MAXOR[i,j]=max(MAXOR[i,j-1],num[j]^字典樹)。

然後問題來了,字典樹怎麽限定邊界呢? ------可持久化實現。

那麽對於每個詢問,只有[L,相應塊的右邊界]需要在持久化Trie裏找最大,然後結合預先處理的[L的右邊界,R]得到結果。

SPOJ MAXOR (分塊 || 可持久化字典樹 || 異或)(好題)