zoukankan      html  css  js  c++  java
  • [note]可持久化Trie

    可持久化Trie

    参考可持久化线段树的思想,修改的时候先直接复制,再对需要修改的点新建节点
    可持久化Trie也是同样的做法,假设现在需要在原本Trie的基础上插入一个字符串
    先把上个Trie的对应节点信息复制过来,对(son[ch])新建节点

    void insert(int x,int y,char*st){
    	int l=strlen(st);
    	for(int i=0;i<l;i++){
    		int k=st[i]-'a';t[x].ch[k]=++tot;//新建
    		x=t[x].ch[k];y=t[y].ch[k];
    		t[x]=t[y];t[x].v++;//复制并更新
    	}
    }
    

    查询先确定rt,然后类似Trie一样直接把字符串丢进去查即可

    int query(int u,char*st){
    	int l=strlen(st);
    	for(int i=0;i<l;i++){
    		int k=st[i]-'a';
    		if(!t[u].ch[k])return 0;
    		u=t[u].ch[k];
    	}
    	return t[u].v;
    }
    

    或者你二进制Trie是这么查的(下面是在一个区间中查异或max的模板)

    int query(int x,int y,int num){
    	int res=0;
    	for(int i=24;i>=0;i--){
    		int k=num>>i&1^1;
    		if(t[y].ch[k]-t[x].ch[k]==0)k^=1;//没有能使该位为1的数
    		else res|=(1<<i);
    		x=t[x].ch[k];y=t[y].ch[k];
    	}
    	return res;
    }
    

    空间=Trie的空间*log
    主要是一些字符串或者序列异或的题目中使用,注意到和主席树一样是可减的

    常见套路

    • 路径问题就维护根到i的前缀Trie,然后把u,v,lca拿出来搞一搞
    • 子树问题求dfn,rk,直接按dfn跑一遍前缀Trie,之后当区间处理
  • 相关阅读:
    vs 编译加速
    leetcode 1405
    sort 从大到小从小到大
    leetcode1404
    leetcode 1406
    leetcode 1556
    杭电研究生自动登录联网脚本
    Cannot mix incompatible Qt library (version ) with this library (version ) 解决方案
    目标检测算法优化技巧
    特征工程和模型融合--机器学习--思维导图和笔记
  • 原文地址:https://www.cnblogs.com/sdzwyq/p/9923751.html
Copyright © 2011-2022 走看看