题目链接:http://acm.hzau.edu.cn/problem.php?id=1206
——————————————————————————————————————
1206: MathematicalGame
Time Limit: 2 Sec Memory Limit: 1280 MB
Submit: 170 Solved: 26
[Submit][Status][Web Board]
Description
Xiao Ming likes to play mathematical games very much. One day, he gets a sequence of n positive integers. XOR (l , r) is defined as the XOR and of all numbers in a continuous interval. Now, Xiao Ming wants to know the intervals which make the XOR (l , r) become largest.
Require l, r.
Input
There is an integer T at the first line, indicate the case of data.
In each case, there is an integer N at the first line, indicate the length of the sequence. And there are N integers, a1, a2, … , an, at the second line. (N <= 1,000,000)
Output
In each case, the first line is “Case #k:”, k is the number of test cases, the next line includes two integers l and r, which separated by a space.
l, r output in lexicographic order if there are multiple results.
Sample Input
1
5
1 2 3 4 5
Sample Output
Case #1:
3 4
————————————————————————————————————————
题目大意:
问你区间异或值最大的区间是多少,如果值有多个,输出字典序最小的那个
解题思路:
相信大家都会 区间内选两个值,异或最大
那么这个也一样,只要维护的是前缀异或和就好了,这样就变成了经典问题。
然后维护结果就好了
附本题代码
——————————————————————————————————
#include <bits/stdc++.h>
typedef long long int LL;
using namespace std;
const int N = 2e6+7;
//const int INF = (~(1<<31));
int read(){
int x=0,f=1;char ch = getchar();
while(ch<'0'||ch>'9') ch = getchar();
while('0'<=ch&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch = getchar();}
return x;
}
/*******************************************/
int n,a,x;
int trie[N*31][2],val[N*31],cnt;
int l,r,mx;
void inserttrie(int x,int id){
int now=0,bt;
for(int i=30;i>=0;i--){
bt = (x&(1<<i))?1:0;
if(!trie[now][bt]) trie[now][bt] = ++cnt;
now=trie[now][bt];
}
if(-1==val[now]) val[now]=id;
}
int ask(int x,int y){
// printf("%d ->" ,x);
int now=0,bt,v=0;
for(int i=30;i>=0;i--){
bt = (x&(1<<i))?1:0;
//printf("%d",bt);
if(trie[now][1-bt]) bt=1-bt,v|=(1<<i);
now=trie[now][bt];
}
// puts(" <-");
int vn = val[now]+1;
// printf("%d %d\n",v,mx);
if(v>mx) mx=v,l=vn,r=y;
if(v==mx){if(vn<l||vn==l&&y<r)l=vn,r=y;}
}
int main(){
memset(trie,0,sizeof(trie));
memset(val,-1,sizeof(val));
int _,kcase = 0;
scanf("%d",&_);
while(_--){
scanf("%d",&n);l=r=1;
a=0;cnt=0;mx=0;
inserttrie(a,0);
for(int i=1;i<=n;i++){
scanf("%d",&x);
a^=x;
// printf("%d%c",a,(i==n)?'\n':' ');
ask(a,i);
inserttrie(a,i);
}
printf("Case #%d:\n",++kcase);
printf("%d %d\n",l,r);
for(int i=0;i<=cnt;i++){
trie[i][0]=trie[i][1]=0;
val[i]=-1;
}
}
return 0;
}