题目


分析

显然树上的问题可以转换成根节点到两点的答案减去2倍根节点到LCA的答案

化边为点,考虑子节点承接父节点的trie,再加入一条新的字符串,

在循环的过程中统计一个位置被多少个字符串经过,

这样在查询的时候直接访问某个trie跳到末尾找到答案


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=100101; char s[N][11];
struct node{int y,next;}e[N<<1];
int Len[N],trie[N*10][26],sum[N*10],n,k=1,dep[N];
int dfn[N],son[N],top[N],fat[N],as[N],rt[N],Tot,tot,big[N];
inline signed iut(){
rr signed ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed Insert(int Rt,int j){
rr int trt=++Tot;
for (rr int i=1;i<=Len[j];++i){
for (rr int p=0;p<26;++p)
trie[Tot][p]=trie[Rt][p];
sum[Tot]=sum[Rt]+1;
trie[Tot][s[j][i]-97]=Tot+1,
Rt=trie[Rt][s[j][i]-97],++Tot;
}
sum[Tot]=sum[Rt]+1;
for (rr int p=0;p<26;++p)
trie[Tot][p]=trie[Rt][p];
return trt;
}
inline signed query(int Rt){
for (rr int j=1;j<=Len[0];++j)
Rt=trie[Rt][s[0][j]-97];
return sum[Rt];
}
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,son[x]=1;
for (rr int i=as[x],mson=-1;i;i=e[i].next)
if (e[i].y!=fa){
rt[e[i].y]=Insert(rt[x],i>>1);
dfs1(e[i].y,x),son[x]+=son[e[i].y];
if (son[e[i].y]>mson) big[x]=e[i].y,mson=son[e[i].y];
}
}
inline void dfs2(int x,int linp){
dfn[x]=++tot,top[x]=linp;
if (!big[x]) return; dfs2(big[x],linp);
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=fat[x]&&e[i].y!=big[x])
dfs2(e[i].y,e[i].y);
}
inline signed Lca(int x,int y){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) x^=y,y^=x,x^=y;
x=fat[top[x]];
}
if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
return x;
}
signed main(){
n=iut();
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut();
e[++k]=(node){y,as[x]},as[x]=k;
e[++k]=(node){x,as[y]},as[y]=k;
rr char c=getchar();
while (!isalpha(c)) c=getchar();
while (isalpha(c)) s[i][++Len[i]]=c,c=getchar();
}
dfs1(1,0),dfs2(1,1);
for (rr int Q=iut();Q;--Q,putchar(10)){
rr int x=iut(),y=iut(),lca=Lca(x,y);
rr char c=getchar(); Len[0]=0;
while (!isalpha(c)) c=getchar();
while (isalpha(c)) s[0][++Len[0]]=c,c=getchar();
print(query(rt[x])+query(rt[y])-2*query(rt[lca]));
}
return 0;
}

#trie,树链剖分#洛谷 6088 [JSOI2015]字符串树的更多相关文章

  1. AC日记——【模板】树链剖分 洛谷 P3384

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  2. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  3. 树链剖分 - Luogu 3384【模板】树链剖分

    [模板]树链剖分 题目描述 已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操 ...

  4. 树剖+线段树||树链剖分||BZOJ1984||Luogu4315||月下“毛景树”

    题面:月下“毛景树” 题解:是道很裸的树剖,但处理的细节有点多(其实是自己线段树没学好).用一个Dfs把边权下移到点权,用E数组记录哪些边被用到了:前三个更新的操作都可以合并起来,可以发现a到b节点间 ...

  5. poj 3237 树链剖分模板(用到线段树lazy操作)

    /* 本体在spoj375的基础上加了一些操作,用到线段树的lazy操作模板类型 */ #include<stdio.h> #include<string.h> #includ ...

  6. 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)

    题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  7. 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点

    题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...

  8. 【模板时间】◆模板·II◆ 树链剖分

    [模板·II]树链剖分 学长给我讲树链剖分,然而我并没有听懂,还是自学有用……另外感谢一篇Blog +by 自为风月马前卒+ 一.算法简述 树链剖分可以将一棵普通的多叉树转为线段树计算,不但可以实现对 ...

  9. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

  10. HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分

    树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...

随机推荐

  1. 如何保证消息顺序执行(Rabbitmq/kafka)

    转载: https://www.cnblogs.com/-wenli/p/13047059.html https://www.jianshu.com/p/02fdcb9e8784

  2. 红胖子(红模仿)的博文大全:开发技术集合大版本更新v4.0.0

    <红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术.树莓派.三维.OpenCV.OpenGL.ffmpeg.OSG.单片机.软硬结合等等)持续更新中...>大版本更新,更新后版本 ...

  3. queryset高级用法:select_related

    在提取某个模型的数据的同时,也提前将相关联的数据提取出来.比如提取文章数据,可以使用select_related将author信息提取出来,以后再次使用article.author的时候就不需要再次去 ...

  4. 网络安全-Linux常用命令

    安装上传下载的软件包 yum install lrzsz -y 下载:linux-->windows sz -y /etc/hosts 上传:windows-->linux rz -y 系 ...

  5. JS笔记:方法两次调用,执行不同分支(公共变量,闭包,类三种方法实现)

    好家伙,   当我们对一个方法进行两次调用,我们希望第一次执行A分支,第二次执行B分支,该怎么做? 这意味着在连续的两次调用中,方法的执行逻辑会交替执行不同的分支. 方法一:公共变量 let flag ...

  6. Linux操作系统不同文件类型区别?

    蓝色代表目录,绿色代表可执行文件,红色代表压缩文件.浅蓝色表示连接文件.白色表示其他文件 相关目录及作用: Bin : 存放普通用户可执行的指令 Boot: 开机引导目录 Dev:设备目录 Etc: ...

  7. Postman/Jmeter工具实现接口测试,为什么还要用代码来实现接口自动化测试?

    这种工具包括一些开源框架最大缺点就是不够灵活,如果是单接口的测试还行,但是有的项目接口比较庞大和负责,这种情况下就不大适用工具(工具适用于小型项目,代码适用于中大型项目) 主要有以下几个原因: 1敏捷 ...

  8. ElasticSearch基本查询使用(2)

    在介绍本章之前,需要先打开安装的Kibana页面, 并打开命令行工具页面: 并且根据上节的介绍,我们需要根据中文搜索,所以需要在建立映射时,指定中文字段的分词器为Ik分词器, 默认为英文分词器,每个中 ...

  9. gitlab推送代码触发jenkins构建

    预期:推送devloop或者master分支的代码, 自动执行jenkins 发布测试环境 首先,jenkins中需要安装如下插件 打开一个任务配置,构建触发器中勾选"Build when ...

  10. Springboot+POI实现excel生成下载进阶版(单元格合并,多Sheet,各种样式处理)

    上周五来了新的需求,基本上我写的还款那一系列流程不要了(我好悲伤,当时写了很久的,逻辑复杂的写的我很骄傲),新的变成如上所示(仅仅一部分),勾选几笔后生成一个excel表格,不同的融资编号所引发的那堆 ...