P4735 最大异或和
Posted snowy2002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4735 最大异或和相关的知识,希望对你有一定的参考价值。
题目描述
给定一个非负整数序列{a},初始长度为N。
有M个操作,有以下两种操作类型:
A x
:添加操作,表示在序列末尾添加一个数x,序列的长度N+1。
Q l r x
:询问操作,你需要找到一个位置p,满足l≤p≤r,使得: a[p]⊕a[p+1]⊕...⊕a[N]⊕x 最大,输出最大是多少。
输入输出格式
输入格式:第一行包含两个整数N,M,含义如问题描述所示。
第二行包含 N个非负整数,表示初始的序列A 。
接下来 M行,每行描述一个操作,格式如题面所述。
假设询问操作有 T 个,则输出应该有 T 行,每行一个整数表示询问的答案。
输入输出样例
输入样例#1:
5 5 2 6 4 3 6 A 1 Q 3 5 4 A 4 Q 5 7 0 Q 3 6 6
输出样例#1:
View Code
4 5 6
关于这道题思路就不再多说,主要讲一下细节问题。
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<map> 7 #include<algorithm> 8 #include<stack> 9 #include<queue> 10 #include<vector> 11 #define maxn 600005 12 using namespace std; 13 14 inline int read() 15 { 16 int x=1,res=0; 17 char c=getchar(); 18 while(c<‘0‘||c>‘9‘) 19 { 20 if(c==‘-‘) 21 x=-1; 22 c=getchar(); 23 } 24 while(c>=‘0‘&&c<=‘9‘) 25 { 26 res=res*10+(c-‘0‘); 27 c=getchar(); 28 } 29 return res*x; 30 } 31 32 int n,m,tot,aa; 33 int last[maxn*24],root[maxn],s[maxn]; 34 int tree[maxn*24][2]; 35 36 void trie(int i,int k,int l,int r) 37 { 38 if(k<0) 39 { 40 last[r]=i; 41 return; 42 } 43 int c=(s[i]>>k)&1; 44 if(l) tree[r][c^1]=tree[l][c^1]; 45 tree[r][c]=++tot; 46 trie(i,k-1,tree[l][c],tree[r][c]); 47 last[r]=max(last[tree[r][0]],last[tree[r][1]]); 48 } 49 50 int ask(int now,int val,int k,int l) 51 { 52 if(k<0) return val^s[last[now]]; 53 int c=val>>k&1; 54 if(last[tree[now][c^1]]>=l)/*如果以这个点为根的子树上的结点的最大编号 55 大于等于l,那么这个结点就有意义,否则,这个结点就没有任何意义*/ 56 { 57 return ask(tree[now][c^1],val,k-1,l); 58 } 59 else 60 { 61 return ask(tree[now][c],val,k-1,l); 62 } 63 } 64 65 int main() 66 { 67 n=read();m=read(); 68 last[0]=-100;/*0号点其实就是trie树上不存在的点,之所以清为负数而不是 69 0,这是因为如果询问的区间的l是1,那么根据我们会把所有last的值>=0(l-1) 70 的数计算进去,这样如果不清为负数,那么trie树上没有的点我们也会错误的 71 计算进去,所以last一定要清为负数。 72 */ 73 root[0]=++tot;/*这个根节点标记为1是为了和不在trie树上的点区分开 */ 74 trie(0,23,0,1);//先构造一个全0的trie树 75 for(int i=1;i<=n;i++) 76 { 77 aa=read(); 78 s[i]=s[i-1]^aa; 79 root[i]=++tot; 80 trie(i,23,root[i-1],root[i]); 81 } 82 for(int i=1;i<=m;i++) 83 { 84 char c; 85 scanf("%s",&c); 86 if(c==‘A‘) 87 { 88 aa=read(); 89 root[++n]=++tot; 90 s[n]=s[n-1]^aa; 91 trie(n,23,root[n-1],root[n]); 92 } 93 else 94 { 95 int l,r,x; 96 l=read();r=read();x=read(); 97 printf("%d ",ask(root[r-1],s[n]^x,23,l-1)); 98 } 99 } 100 }
以上是关于P4735 最大异或和的主要内容,如果未能解决你的问题,请参考以下文章