您的位置:首页 > 其它

【BZOJ】【3261】最大异或和

2015-06-04 22:39 369 查看

可持久化Trie

  嗯……同样搞个前缀异或和,然后将x与sum异或一下,就是在[l-1,r-1]中找x^sum的最大异或值了。同样可持久化Trie搞搞即可(模板还是没背全啊……sad

/**************************************************************
Problem: 3261
User: Tunix
Language: C++
Result: Accepted
Time:3888 ms
Memory:239552 kb
****************************************************************/

//BZOJ 3261
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline int getint(){
int r=1,v=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
return r*v;
}
const int N=20000010;
/*******************template********************/

int n,m,t
[2],tot,rt[1000010],id
;
inline void Ins(int pre,int x,int k){
int now=rt[k]=++tot; id[tot]=k;
D(i,30,0){
int j=(x>>i)&1;
t[now][j^1]=t[pre][j^1];
t[now][j]=++tot; id[tot]=k; now=tot;
pre=t[pre][j];
}
}
inline int ask(int l,int r,int x){
int ans=0,now=rt[r];
D(i,30,0){
int j=((x>>i)&1)^1;
if (id[t[now][j]]>=l) ans|=1<<i; else j^=1;
now=t[now][j];
}
return ans;
}

int main(){
#ifndef ONLINE_JUDGE
freopen("3261.in","r",stdin);
freopen("3261.out","w",stdout);
#endif
n=getint(); m=getint();
id[0]=-1;
Ins(rt[0],0,0);
int sum=0;
F(i,1,n){
sum^=getint();
Ins(rt[i-1],sum,i);
}
char cmd[5]; int x,l,r;
F(i,1,m){
scanf("%s",cmd);
if (cmd[0]=='A'){
sum^=getint();
Ins(rt
,sum,n+1); n++;
}else{
l=getint(); r=getint(); x=getint();
printf("%d\n",ask(l-1,r-1,sum^x));
}
}
return 0;
}


View Code

3261: 最大异或和

Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 743 Solved: 323
[Submit][Status][Discuss]

Description

[align=left] [/align]
给定一个非负整数序列 {a},初始长度为 N。

有 M个操作,有以下两种操作类型:

1 、A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1。

2 、Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得:

a[p] xor a[p+1] xor ... xor a
xor x 最大,输出最大是多少。

Input

第一行包含两个整数 N ,M,含义如问题描述所示。

第二行包含 N个非负整数,表示初始的序列 A 。

接下来 M行,每行描述一个操作,格式如题面所述。

Output

假设询问操作有 T个,则输出应该有 T行,每行一个整数表示询问的答案。

Sample Input

5 5

2 6 4 3 6

A 1

Q 3 5 4

A 4

Q 5 7 0

Q 3 6 6

对于测试点 1-2,N,M<=5 。

对于测试点 3-7,N,M<=80000 。

对于测试点 8-10,N,M<=300000 。

其中测试点 1, 3, 5, 7, 9保证没有修改操作。

对于 100% 的数据, 0<=a[i]<=10^7。

Sample Output

4

5

6

HINT

对于 100% 的数据, 0<=a[i]<=10^7 。

Source

[Submit][Status][Discuss]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: