题目描述

萌萌买了一颗字符串树的种子,春天种下去以后夏天就能长出一棵很大的字
符串树。字符串树很奇特,树枝上都密密麻麻写满了字符串,看上去很复杂的样
子。
【问题描述】
字符串树本质上还是一棵树,即N个节点N-1条边的连通无向无环图,节点
从1到N编号。与普通的树不同的是,树上的每条边都对应了一个字符串。萌萌
和JYY在树下玩的时候,萌萌决定考一考JYY。每次萌萌都写出一个字符串S和
两个节点U,V,需要JYY立即回答U和V之间的最短路径(即,之间边数最少的
路径。由于给定的是一棵树,这样的路径是唯一的)上有多少个字符串以为前
缀。
JYY虽然精通编程,但对字符串处理却不在行。所以他请你帮他解决萌萌的难题。

输入

输入第一行包含一个整数N,代表字符串树的节点数量。
接下来N-1行,每行先是两个数U,V,然后是一个字符串S,表示节点和U节
点V之间有一条直接相连的边,这条边上的字符串是S。输入数据保证给出的是一
棵合法的树。
接下来一行包含一个整数Q,表示萌萌的问题数。
接来下Q行,每行先是两个数U,V,然后是一个字符串S,表示萌萌的一个问
题是节点U和节点V之间的最短路径上有多少字符串以S为前缀。
输入中所有字符串只包含a-z的小写字母。
1<=N,Q<=100,000,且输入所有字符串长度不超过10。

输出

输出Q行,每行对应萌萌的一个问题的答案。

样例输入

4
1 2 ab
2 4 ac
1 3 bc
3
1 4 a
3 4 b
3 2 ab

样例输出

2
1
1
 
在原树上每个点建一个版本的可持久化$trie$树,每个点的可持久化$trie$树继承父节点的$trie$树并将它与父节点边上的字符串加入到这个点的$trie$树中。查询一个串是多少个串的前缀直接在$trie$树上跑到对应点取这个点子树大小即可。由于每个点的$trie$树保存了这个点到根路径上字符串的信息,所以每次询问的答案就是$query(u)+query(v)-2*query(lca(u,v))$。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct miku
{
int son[28],sum;
}s[1000010];
int n,m;
int x,y;
int cnt;
int root[100010];
int head[100010];
int next[200010];
char ch[100010][12];
int to[200010];
int tot;
int f[100010][19];
int dep[100010];
char rd[12];
int id[200010];
void add(int x,int y,int i)
{
next[++tot]=head[x];
head[x]=tot;
to[tot]=y;
id[tot]=i;
}
int build(int pre,int dep,char *ch,int lim)
{
int rt=++cnt;
s[rt]=s[pre];
s[rt].sum++;
if(dep==lim)
{
return rt;
}
s[rt].son[ch[dep]-'a']=build(s[pre].son[ch[dep]-'a'],dep+1,ch,lim);
return rt;
}
void dfs(int x)
{
for(int i=1;i<=17;i++)
{
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x][0])
{
f[to[i]][0]=x;
dep[to[i]]=dep[x]+1;
root[to[i]]=build(root[x],0,ch[id[i]],strlen(ch[id[i]]));
dfs(to[i]);
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])
{
swap(x,y);
}
int d=dep[x]-dep[y];
for(int i=0;i<=17;i++)
{
if(d&(1<<i))
{
x=f[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=17;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int query(int rt,int lim)
{
for(int i=0;i<lim;i++)
{
rt=s[rt].son[rd[i]-'a'];
}
return s[rt].sum;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d%s",&x,&y,ch[i]);
add(x,y,i);
add(y,x,i);
}
dfs(1);
scanf("%d",&m);
while(m--)
{
scanf("%d%d%s",&x,&y,rd);
int anc=lca(x,y);
int len=strlen(rd);
printf("%d\n",query(root[x],len)+query(root[y],len)-2*query(root[anc],len));
}
}

BZOJ4477[Jsoi2015]字符串树——可持久化trie树的更多相关文章

  1. 【BZOJ-4212】神牛的养成计划 Trie树 + 可持久化Trie树

    4212: 神牛的养成计划 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 136  Solved: 27[Submit][Status][Discus ...

  2. 【BZOJ4212】神牛的养成计划 Trie树+可持久化Trie树

    [BZOJ4212]神牛的养成计划 Description Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变 ...

  3. 4.24 省选模拟赛 欧珀瑞特 主席树 可持久化trie树

    很容易的一道题目.大概.不过我空间计算失误MLE了 我草草的计算了一下没想到GG了. 关键的是 我学了一个dalao的空间回收的方法 但是弄巧成拙了. 题目没有明确指出 在任意时刻数组长度为有限制什么 ...

  4. BZOJ 4477: [Jsoi2015]字符串树 可持久化trie树

    这个是真——可持久化字典树..... code: #include <bits/stdc++.h> #define N 100006 #define setIO(s) freopen(s& ...

  5. luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树

    LINK:字符串树 先说比较简单的正解.由于我没有从最简单的考虑答案的角度思考 所以... 下次还需要把所有角度都考察到. 求x~y的答案 考虑 求x~根+y~根-2*lca~根的答案. 那么问题变成 ...

  6. 【BZOJ3439】Kpm的MC密码 Trie树+可持久化线段树

    [BZOJ3439]Kpm的MC密码 Description 背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当 ...

  7. 【bzoj3261】【最大异或和】可持久化trie树+贪心

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61705397 Description 给定一个非 ...

  8. 【bzoj3439】Kpm的MC密码 可持久化Trie树

    题目描述 背景 想Kpm当年为了防止别人随便进入他的MC,给他的PC设了各种奇怪的密码和验证问题(不要问我他是怎么设的...),于是乎,他现在理所当然地忘记了密码,只能来解答那些神奇的身份验证问题了. ...

  9. 可持久化Trie树初步

    可持久化Trie树和可持久化线段树很像,依次插入信息,通过减法来进行历史版本查询. 2015年11月27日 bzoj3261 最大异或和 我们需要计算 a[p] xor a[p+1] xor ... ...

随机推荐

  1. 单点登录SSO:图示和讲解

    目录 概述 示例运行效果动画 跨域Web SSO时序图 代码截图 几个基本概念 涉及的站点和页面 重点理解:单点登录的核心步骤 敢说最准确的单点登录图示,因为: 我严格对照所画时序图的每个步骤,开发了 ...

  2. Python实现将爱词霸每日一句定时推送至微信

    前言 前几天在网上看到一篇文章<教你用微信每天给女票说晚安>,感觉很神奇的样子,随后研究了一下,构思的确是巧妙.好,那就开始动工吧!服务器有了,Python环境有了,IDE打开了...然而 ...

  3. Can’t connect to local MySQL server through socket 原因解析

    在连接mysql的时,经常会出现以下错误提示: ERROR (HY000): Can't connect to local MySQL server through socket '/var/lib/ ...

  4. 插入排序专题 直接插入 折半 希尔shell

    1.直接插入排序 分析:a[n]有n个元素 a[0...n-1]  从 i=1...n-1  a[i]依次与   a[0...n-2]数字进行比较 发现后面的数字大于前面的数字交换位置,每一次比较,与 ...

  5. HNOI2013 BZOJ3144 切糕

    在n×m的表格上,在(x,y)填v的代价是w(x,y,v),且相邻格子填的数相差≤d.求填满表格的最小代价.n,m,maxv≤40. 每个点上选择一个数填,因此将上面的数串起来.考虑限制条件,矛盾条件 ...

  6. MySQL 遇到的问题以及解决方案

    Problem: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysq ...

  7. marMariaDB & MYSQL flexviews

    Using Flexviews - part one, introduction to materialized views - Percona Database Performance Bloght ...

  8. python自动化常见问题汇总

           1.如何提高selenium脚本的执行速度? Selenium脚本的执行速度受多方面因素的影响,如网速,操作步骤的繁琐程度,页面加载的速度,以及我们在脚本中设置的等待时间,运行脚本的线程 ...

  9. vue传参二

    <template> <ul> <li v-for="(value,key,index) in list" :key="index" ...

  10. CMake--List用法

    list(LENGTH <list><output variable>) list(GET <list> <elementindex> [<ele ...