可持久化trie树

  可持久化的大意为:在更新之后,原来的数据结构也可以保存下来,再添加了一条串之后,未添加此串的线段树也仍然存在。

   暴力:不就是更新一次建一颗树嘛

    算法:通过只把新加入的内容做添加新点,多个祖结点作为多棵树的起点达到其目的,不需要多开很多点,只需多开根节点,和每次最多会多开新串的长度那么多的点即可达到。

此处借acwing上大佬题解一用

 之后便是上代码(插入二进制串)

void insert(int u)
{
    root[u]=++idx;
    int num=s[u];
    int p=root[u];
    int lt_p=0;
    if(u) lt_p=root[u-1];
    for(int i=23;i>=0;i--)
    {
        int v=num>>i&1;
        if(lt_p)
        {
            tr[p][!v]=tr[lt_p][!v];
            lt_p=tr[lt_p][v];
        }
        tr[p][v]=++idx;
        p=tr[p][v];
        max_id[idx]=u;
    }
    //max_id[p]=u;
}

                    

然后查询最大异或

int query(int root,int c,int l)
{
    int p=root;
    for(int i=23;i>=0;i--)
    {
        int v=c>>i&1;
        if(max_id[tr[p][!v]]>=l)
        {
            p=tr[p][!v];
        }
        else p=tr[p][v];
    }
    return c^s[max_id[p]];//最后p所处点的max_id将会成为最大的s的指向
}

                    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值