zoukankan      html  css  js  c++  java
  • 可持久化字典树

    赶锅中

    咕咕咕

    $ iny ext{前置知识:字典树(trie),可持久化线段树(主席树)}$

    简介

    可持久化字典树(可持久化trie)是一种可以查询历史版本的字符串的数据结构。它支持末尾插入,区间查询,相当于多叉、不平衡的主席树。

    原理

    同主席树。

    实现

    对于每一个节点,需要记录的信息类似于普通的trie,添加新点时需要把(last)节点的所有到儿子的转移复制到新节点上。

    //普通可持久化trie模板
    int tr[1000002][27],tot=0;
    int root[100002],totrt=0;
    void push(int n,char a[])
    {
    	int Last=root[totrt],Now=(root[++totrt]=++tot);a[n+1]='a'+26;
    	for(int i=1;i<=n+1;i++)
    	{
    		for(int j=0;j<=26;j++)tr[Now][j]=tr[Last][j];
    		tr[Now][a[i]-'a']=++tot;
    		Now=tr[Now][a[i]-'a'];
    		Last=tr[Last][a[i]-'a'];
    	}
    }
    bool find(int n,char a[],int l,int r)
    {
    	l=rt[l-1],r=rt[r];
    	for(int i=1;i<=n;i++)
    	{
    		if(tr[l][a[i]-'a']==tr[r][a[i]-'a'])return 0;
    		l=tr[l][a[i]-'a'];
    		r=tr[r][a[i]-'a'];
    	}
    	return tr[r][26]!=tr[l][26];
    }
    
    //可持久化01trie模板
    int s[10000002][2],v[10000002],rt[100002],tot=0,tot0=0;
    inline void push(int p)
    {
    	int l=rt[tot0],r=(rt[++tot0]=++tot);
    	for(register int i=30;i>=0;i--)
    	{
    		s[r][bool((1<<i)&p)]=++tot;
    		s[r][!bool((1<<i)&p)]=s[l][!bool((1<<i)&p)];
    		l=s[l][bool((1<<i)&p)];
    		r=s[r][bool((1<<i)&p)];
    	}
    	v[r]=tot0;
    }
    

    应用

    区间查询字符串、区间最大异或和(可持久化01trie)……

    Please not contact lydsy2012@163.com!
  • 相关阅读:
    linux——进程管理
    linux——软件管理
    linux——压缩打包
    linux——输入输出
    linux——ACL控制
    linux——特殊权限
    linux——基本权限
    linux——用户管理
    单源最短路spfa(队列优化)
    getline读取
  • 原文地址:https://www.cnblogs.com/ztc03/p/chijiuable_trie.html
Copyright © 2011-2022 走看看