BZOJ4477: [Jsoi2015]字符串树
【传送门:BZOJ4477】
简要题意:
给出一棵n个点的树,树上的边都代表一个字符串,给出Q个询问,每个询问输入x,y和字符串s,求出x到y的路径上以s为前缀的字符串个数
题解:
自己yy了一波可持久化字典树
将每条边的字符串放到深度更深的节点保存
对于x到y的路径,将rt[x]+rt[y]-2*rt[lca]就可以了,因为我们不需要lca到它父亲的字符串
本机RE,提交AC。。。怕是机子出毛病了
参考代码:
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
struct trie
{
int son[],c;
trie()
{
c=;
memset(son,,sizeof(son));
}
}tr[];int trlen;
int rt[];
struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
char st[];
int slen;
void Link(int &u1,int d)
{
if(u1==) u1=++trlen;
tr[u1].c=;
if(d==slen) return ;
d++;
int y=st[d]-'a'+;
Link(tr[u1].son[y],d);
}
void Merge(int &u1,int u2)
{
if(u1==){u1=u2;return ;}
if(u2==) return ;
tr[u1].c+=tr[u2].c;
for(int i=;i<=;i++) Merge(tr[u1].son[i],tr[u2].son[i]);
}
int f[][],bin[],dep[];
void dfs(int x)
{
for(int i=;bin[i]<=dep[x];i++) f[x][i]=f[f[x][i-]][i-];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=f[x][])
{
f[y][]=x;
dep[y]=dep[x]+;
Merge(rt[y],rt[x]);
dfs(y);
}
}
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=;i>=;i--)
{
if(dep[x]-dep[y]>=bin[i])
{
x=f[x][i];
}
}
if(x==y) return x;
for(int i=;i>=;i--)
{
if(dep[x]>=bin[i]&&f[x][i]!=f[y][i])
{
x=f[x][i];y=f[y][i];
}
}
return f[x][];
}
char s[];int clen;
int findc(int u1,int u2,int u3,int d)
{
int c=tr[u1].c+tr[u2].c-*tr[u3].c;
if(c==) return ;
if(d==clen) return c;
d++;
int y=s[d]-'a'+;
return findc(tr[u1].son[y],tr[u2].son[y],tr[u3].son[y],d);
}
int main()
{
bin[]=;for(int i=;i<=;i++) bin[i]=bin[i-]<<;
int n;
scanf("%d",&n);
len=;memset(last,,sizeof(last));
trlen=;memset(rt,,sizeof(rt));
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d%s",&x,&y,st+);slen=strlen(st+);
ins(x,y);
Link(rt[y],);
}
f[][]=;dep[]=;dfs();
int Q;
scanf("%d",&Q);
for(int i=;i<=Q;i++)
{
int x,y;
scanf("%d%d%s",&x,&y,s+);
clen=strlen(s+);
int lca=LCA(x,y);
printf("%d\n",findc(rt[x],rt[y],rt[lca],));
}
return ;
}
BZOJ4477: [Jsoi2015]字符串树的更多相关文章
- BZOJ4477[Jsoi2015]字符串树——可持久化trie树
题目描述 萌萌买了一颗字符串树的种子,春天种下去以后夏天就能长出一棵很大的字符串树.字符串树很奇特,树枝上都密密麻麻写满了字符串,看上去很复杂的样子.[问题描述]字符串树本质上还是一棵树,即N个节点N ...
- BZOJ4477 JSOI2015字符串树(可持久化trie)
树上建可持久化trie即可,有点过于裸了.darkbzoj过了然而在bzoj一直wa,不知道哪有锅. #include<iostream> #include<cstdio> # ...
- [bzoj4477 Jsoi2015]字符串树 (可持久化trie)
传送门 Solution 复习下tire( ̄▽ ̄)/ 裸的可持久化tire,我用树剖求了下LCA Code #include <cstdio> #include <cstring&g ...
- 【BZOJ4477】[JSOI2015]字符串树(Trie树)
[BZOJ4477][JSOI2015]字符串树(Trie树) 题面 BZOJ 题解 对于每个点维护其到根节点的所有字符串构成的\(Trie\),显然可持久化一下就很好写了. 然后每次询问就是\(u+ ...
- [Jsoi2015]字符串树
https://www.zybuluo.com/ysner/note/1298148 题面 字符串树本质上还是一棵树,即\(N\)个节点\(N-1\)条边的连通无向无环图,节点 从\(1\)到\(N\ ...
- luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
LINK:字符串树 先说比较简单的正解.由于我没有从最简单的考虑答案的角度思考 所以... 下次还需要把所有角度都考察到. 求x~y的答案 考虑 求x~根+y~根-2*lca~根的答案. 那么问题变成 ...
- 【BZOJ4477】字符串树(可持久化Trie)
此题花费我整整三天的功夫.还在NoiP贴吧发过贴. 最后发现trie树建新节点时信息未完全复制,真是愚蠢之极. 言归正传. 如果我们已经知道了每个点上的trie树那么询问就是sum[x]+sum[y] ...
- BZOJ 4477: [Jsoi2015]字符串树 可持久化trie树
这个是真——可持久化字典树..... code: #include <bits/stdc++.h> #define N 100006 #define setIO(s) freopen(s& ...
- 「JSOI2015」字符串树
「JSOI2015」字符串树 传送门 显然可以树上差分. 我们对于树上每一条从根出发的路径都开一 棵 \(\text{Trie}\) 树,那么我们就只需要在 \(\text{Trie}\) 树中插入一 ...
随机推荐
- DQL命令(查询)
select *或字段1,字段2... from 表名 [where 条件] 提示:*符号表示取表中所有列:没有where语句表示 查询表中所有记录:有wh ...
- HDU 4253 Two Famous Companies
Two Famous Companies Time Limit: 15000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...
- Servlet里面一调用Dao里的某个方法
背景: 这几天,由于项目集成的需要,我要在doFilter里调用dao层里的某些方法,可是总之报空指针,只要调用那个dao方法,就报错误.很是纳闷,网上查找了各种原因,终于让我给突破了,看来还是Jav ...
- HDU 4314 Contest 2
可以知道,逃出的人中,最后一个应当是A+B最长的,这是很容易发现的.那么,最选逃出去的必定是A+B最短的.这符合最优. 于是,可以把各小矮人按A+B的和由大到小排序.定义DP[i][j]为i个人中逃出 ...
- java中的system.out.println()和JSP中out.println()差别
out.println()输出到client. 在out.println()中,out是response的实例.是以response为对象进行流输出的,即将内容输出到client.假设在JSP ...
- Android笔记三十三.BroadcastReceiver使用
广播是一种广泛运用在应用程序之间传输信息的机制,而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件. BroadcastReceiver本质上是一种全局监听器. ...
- Codeforces 701E Connecting Universities 贪心
链接 Codeforces 701E Connecting Universities 题意 n个点的树,给你2*K个点,分成K对,使得两两之间的距离和最大 思路 贪心,思路挺巧妙的.首先dfs一遍记录 ...
- JavaScript学习——使用JS完成省市二级联动
1.我们希望在注册页面中添加一个字段(籍贯),当用户选择一个具体的省份,在后面的下拉列表中动态加载该省份下所有的城市.显示的效果如下: 2.步骤分析: 第一步:确定事件(onchange)并为其绑定一 ...
- <ItemTemp>里写判断语句
<%@ Language="C#" %> <html> <head></head> <body> <%=DateT ...
- crontab中使用sudo命令的注意
在使用crontab执行非root用户定时任务时,有时候shell脚本里需要用到sudo以获得root权限: 如: VIP_CARD=eth0 VIP_ADDR=192.168.4.119 NETMA ...