[bzoj4477 Jsoi2015]字符串树 (可持久化trie)

Posted Menteur_hxy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj4477 Jsoi2015]字符串树 (可持久化trie)相关的知识,希望对你有一定的参考价值。

传送门

Solution

复习下tire( ̄▽ ̄)/
裸的可持久化tire,我用树剖求了下LCA

Code

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define E(i,u) for(register int i=head[u],v;i;i=E[i].nxt)
using namespace std;

inline int read() {
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    return x*f;
} 

const int N=1e5+10;
int n,cnt,tot,q;
int head[N],fa[N],top[N],dep[N],rt[N],siz[N],son[N];
char ch[N][20];
struct Edge{int to,nxt;char *ch;}E[N<<1];
struct Node{int son[27],val;}nd[N<<4];

inline void add(int u,int v,char *s) {E[++cnt]=(Edge){v,head[u],s};head[u]=cnt;}

void ins(int o1,int &o2,int dep,char *s,int len) {
    nd[o2=++tot]=nd[o1];nd[o2].val++;if(dep>len) return ;
    ins(nd[o1].son[s[dep]-'a'],nd[o2].son[s[dep]-'a'],dep+1,s,len);
}

int qry(int o,char *s,int len) {
    F(i,1,len) o=nd[o].son[s[i]-'a'];
    return nd[o].val;
}

void dfs1(int u,int pre) {
    siz[u]=1;fa[u]=pre;dep[u]=dep[pre]+1;
    E(i,u) if((v=E[i].to)!=pre) {
        ins(rt[u],rt[v],1,E[i].ch,strlen(E[i].ch+1));
        dfs1(v,u); siz[u]+=siz[v];
        if(siz[son[u]]<siz[v]) son[u]=v;
    }
}

void dfs2(int u,int pre) {
    if(son[pre]==u) top[u]=top[pre]; else top[u]=u;
    if(son[u]) dfs2(son[u],u);
    E(i,u) if((v=E[i].to)!=pre&&v!=son[u]) dfs2(v,u);
}

int LCA(int x,int y) {
    while(top[x]!=top[y]) {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        x=fa[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}

int main() {
    n=read();
    F(i,1,n-1) {
        int a=read(),b=read();scanf("%s",ch[i]+1);
        add(a,b,ch[i]);add(b,a,ch[i]);
    }
    dfs1(1,0);dfs2(1,0);
    q=read();
    while(q--) {
        int u=read(),v=read();scanf("%s",ch[0]+1);
        int len=strlen(ch[0]+1);
        int ans=qry(rt[u],ch[0],len)+qry(rt[v],ch[0],len)
            -2*qry(rt[LCA(u,v)],ch[0],len);
        printf("%d
",ans);
    }
    return 0;
}

以上是关于[bzoj4477 Jsoi2015]字符串树 (可持久化trie)的主要内容,如果未能解决你的问题,请参考以下文章

4477: [Jsoi2015]字符串树

bzoj1014: [JSOI2008]火星人prefix 平衡树-字符串-hash-二分

bzoj4486JSOI2015串分割

「JSOI2015」字符串树

BZOJ 1016: [JSOI2008]最小生成树计数

字符串树「JSOI2015」