【模板】可持久化Trie(可持久化trie)

【模板】可持久化Trie(luogu)

Description

题目描述

给定一个非负整数序列 {a},初始长度为n

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

  1. A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 n+1。
  2. Q l r x:询问操作,你需要找到一个位置 p,满足lpr,使得: a[p]^a[p+1]^...^a[N]^x 最大,输出最大是多少。

输入格式

第一行包含两个整数 N,M,含义如问题描述所示。
第二行包含 N个非负整数,表示初始的序列A
接下来 M行,每行描述一个操作,格式如题面所述。

输出格式

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

Code

#include <cstdio>
#include <cstdlib>
using namespace std;
const int N=6e5+10;
int rt[N],tot,sum,n,m,l,r,x;
char s[5];
struct node
{
    int ch[2],sum;
}f[N*40];
void build(int x,int y,int t,int pos)
{
    if(t<0) return ;
    int wh=(pos>>t)&1;
    f[x].ch[wh^1]=f[y].ch[wh^1];
    f[x].ch[wh]=++tot;
    f[f[x].ch[wh]].sum=f[f[y].ch[wh]].sum+1;
    build(f[x].ch[wh],f[y].ch[wh],t-1,pos);
}
int get(int x,int y,int t,int pos)
{
    if(t<0) return 0;
    int wh=(pos>>t)&1;
    int cn=f[f[y].ch[wh^1]].sum-f[f[x].ch[wh^1]].sum;
    if(cn>0) return (1<<t)+get(f[x].ch[wh^1],f[y].ch[wh^1],t-1,pos);
    else return get(f[x].ch[wh],f[y].ch[wh],t-1,pos);
}
int main()
{
    scanf("%d%d",&n,&m);
    rt[1]=++tot;
    build(rt[1],rt[0],24,0);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        sum^=x;
        rt[i+1]=++tot;
        build(rt[i+1],rt[i],24,sum);
    }
    while(m--)
    {
        scanf("%s",s);
        if(s[0]=='Q')
        {
            scanf("%d%d%d",&l,&r,&x);
            x^=sum;
            printf("%d\n",get(rt[l-1],rt[r],24,x));
        }
        else
        {
            scanf("%d",&x);
            n++,sum^=x;
            rt[n+1]=++tot;
            build(rt[n+1],rt[n],24,sum);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hsez-cyx/p/12275520.html