可持久化字典树
Posted i am back
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可持久化字典树相关的知识,希望对你有一定的参考价值。
1.在数组结尾插入一个数
2.给定l,r,x,求一个l<=p<=r,使x^a[p]^a[p+1]^...^a[n]最大
首先我们可以维护前缀和 然后就是使x^sum[n]^sum[p-1]最大
x^sum[n]为定值,于是用Trie树贪心即可
考虑到l-1<=p-1<=r-1,我们不能对于每个询问都建一棵Trie树,但是我们可以对于Trie数维护前缀和,建立可持久化Trie树
每个区间[l,r]的Trie树为tree[r]-tree[l-1]
一般情况用于求区间内,异或值最大
/* data:2018.04.27 author:gsw link:https://www.nowcoder.com/acm/contest/104/H account:tonygsw */ #define ll long long #define IO ios::sync_with_stdio(false); #include<iostream> #include<math.h> #include<string.h> #include<stdio.h> #include<algorithm> #include<vector> using namespace std; const int maxn=1e5+5; class Node{ public: int cnt,ls,rs; }; Node tr[maxn*40]; int root[maxn];int cnt; int in(int pre,int x,int deep) { int num=++cnt; tr[num]=tr[pre]; tr[num].cnt=tr[pre].cnt+1; if(deep<0)return num; if(!((x>>deep)&1))tr[num].ls=in(tr[pre].ls,x,deep-1); else tr[num].rs=in(tr[pre].rs,x,deep-1); return num; } int query(int l,int r,int x,int deep) { if(deep<0)return 0; if(!((x>>deep)&1))//为0 { if(tr[tr[r].rs].cnt>tr[tr[l].rs].cnt)return (1<<deep)+query(tr[l].rs,tr[r].rs,x,deep-1); else return query(tr[l].ls,tr[r].ls,x,deep-1); } else { if(tr[tr[r].ls].cnt>tr[tr[l].ls].cnt)return (1<<deep)+query(tr[l].ls,tr[r].ls,x,deep-1); else return query(tr[l].rs,tr[r].rs,x,deep-1); } } int main() { int n,x,m,b,l,r; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x); root[i]=in(root[i-1],x,29); } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&b,&l,&r); printf("%d\n",query(root[l-1],root[r],b,29)); } } /* 5 1 6 4 8 7 1 3 2 4 */
以上是关于可持久化字典树的主要内容,如果未能解决你的问题,请参考以下文章