SPOJ MAXOR (分块 || 可持久化字典树 || 异或)(好题)

Posted ---学习ing---

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ MAXOR (分块 || 可持久化字典树 || 异或)(好题)相关的知识,希望对你有一定的参考价值。

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 (分块 || 可持久化字典树 || 异或)(好题)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

第k小问题

SPOJ 3267

spoj 3267 D-query

SPOJ Hacking(字典树 + 搜索)题解

[SPOJ10628]Count on a tree(主席树)