zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    淘宝Banner 轮播图
    JavaScript move简易版运动框架封装
    javaScript 导航栏
    JS 运动框架完整版
    Js 数组操作
    JS 动画轮播效果
    JavaScritpt 字符串操作
    Java AOP切面编程方式
    时间版 运动框架
    Nmon的安装及使用
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9737883.html
Copyright © 2011-2022 走看看