考虑这个问题:
给一个序列A。有$m$个询问,给三个数$l,r,v$,求$\max_{l\le i\le r}a_i\ xor\ v$。强制在线
当$l=1,r=n$,即为01Trie的模板题
考虑当$l=1$时的简化问题。使用可持久化Trie。类似于主席树,依次插入$a_{1..n}$,但不修改原有信息,而是新建一个根$root_i$,再执行插入.
显然以$root_i$为根,同样构成一棵01Trie。询问时在以$root_r$为根的01Trie上查询即可。
对于一般化的情况,每个点再维护一个额外信息$last$,表示子树中最晚的版本编号。查询时,从$root_r$开始走,当儿子的$last\ge l$时才认为这个儿子存在即可。
struct Lasting_Trie
{
ll t[MAXN*33][2],root[MAXN],last[MAXN*33],cnt=0;
ll a[MAXN];
void _insert(ll dex,ll k,ll pre,ll num)
{
if(k<0){last[num]=dex;return;}
bool c=(a[dex]>>k)&1;
if(pre)t[num][!c]=t[pre][!c];
t[num][c]=++cnt;
_insert(dex,k-1,t[pre][c],cnt);
last[num]=max(last[t[num][!c]],last[t[num][c]]);
}
void insert(ll dex,ll val)
{
a[dex]=val;
root[dex]=++cnt;
_insert(dex,31,root[dex-1],root[dex]);
}
ll Query(ll lim,ll dex)
{
ll u=root[dex],res=0;
for(ll i=31;i>=0;--i)
{
bool c=(a[dex]>>i)&1;
if(t[u][!c]&&last[t[u][!c]]>=lim)res+=1ll<<i,u=t[u][!c];
else u=t[u][c];
}
return res;
}
}T;
wh巨佬终于回来了
万弘牛逼