此题花费我整整三天的功夫。还在NoiP贴吧发过贴。

最后发现trie树建新节点时信息未完全复制,真是愚蠢之极。

言归正传。

如果我们已经知道了每个点上的trie树那么询问就是sum[x]+sum[y]-sum[lca(x,y)]*2

然后就是trie树变可持久化。

DFS2中插入所有字符串,建立新节点,复制出现次数与trie树的next指针。

然后就没有然后了。

  map:array[..,'a'..'z']of longint;
t:array[..]of record
s:longint;
end;
root:array[..]of longint;
head,vet,next,dep:array[..]of longint;
f:array[..,..]of longint;
len:array[..]of string;
n,i,x,y,tot,tmp,cnt,j,k,q:longint;
zyd,ch1,ch:string; procedure add(a,b:longint;c:string);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; procedure dfs1(u:longint);
var e,v,i:longint;
begin
for i:= to do
begin
if dep[u]<(<<i) then break;
f[u,i]:=f[f[u,i-],i-];
end;
e:=head[u];
while e<> do
begin
v:=vet[e];
if v<>f[u,] then
begin
dep[v]:=dep[u]+;
f[v,]:=u;
dfs1(v);
end;
e:=next[e];
end;
end; procedure ins(var x:longint;i:longint);
begin
inc(cnt); t[cnt]:=t[x];
map[cnt]:=map[x];
x:=cnt; inc(t[x].s);
if i<=length(zyd) then ins(map[x,zyd[i]],i+);
end; function query(a,b,c,i:longint):longint;
begin
// writeln(a,' ',b,' ',c);
if i>length(zyd) then exit(t[a].s+t[b].s-t[c].s*);
exit(query(map[a,zyd[i]],map[b,zyd[i]],map[c,zyd[i]],i+));
end; procedure dfs2(u:longint);
var e,v:longint;
begin
e:=head[u];
while e<> do
begin
v:=vet[e];
if v<>f[u,] then
begin
root[v]:=root[u];
zyd:=len[e];
ins(root[v],);
dfs2(v);
end;
e:=next[e];
end;
end; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; function lca(x,y:longint):longint;
var i,d:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
for i:= to do
if d and (<<i)> then x:=f[x,i];
for i:= downto do
if f[x,i]<>f[y,i] then
begin
x:=f[x,i]; y:=f[y,i];
end;
if x=y then exit(x);
exit(f[x,]);
end; begin
assign(input,'strings.in'); reset(input);
assign(output,'strings.out'); rewrite(output);
readln(n);
for i:= to n- do
begin
readln(ch);
j:=; x:=;
while (ch[j]>='')and(ch[j]<='') do
begin
x:=x*+ord(ch[j])-ord('');
inc(j);
end;
inc(j); y:=;
while (ch[j]>='')and(ch[j]<='') do
begin
y:=y*+ord(ch[j])-ord('');
inc(j);
end;
inc(j);
ch1:='';
for k:=j to length(ch) do ch1:=ch1+ch[k];
add(x,y,ch1);
add(y,x,ch1);
end; //f[1,0]:=1; dfs1();
dfs2();
readln(q);
for i:= to q do
begin
readln(ch);
j:=; x:=;
while (ch[j]>='')and(ch[j]<='') do
begin
x:=x*+ord(ch[j])-ord('');
inc(j);
end;
inc(j); y:=;
while (ch[j]>='')and(ch[j]<='') do
begin
y:=y*+ord(ch[j])-ord('');
inc(j);
end;
inc(j);
ch1:='';
for k:=j to length(ch) do ch1:=ch1+ch[k];
tmp:=lca(x,y);
zyd:=ch1;
writeln(query(root[x],root[y],root[tmp],));
end; close(input);
close(output);
end.

2016.12.25

学会主席树后重写了一遍,感觉异常轻松

因为此题询问的是边上的信息,所以LCA点不会被重复计算,询问时也就不用-1

如果是点则要-1

 var map:array[..,'a'..'z']of longint;
t:array[..]of longint;
root:array[..]of longint;
head,vet,next,dep,flag:array[..]of longint;
f:array[..,..]of longint;
len:array[..]of string;
n,i,x,y,tot,tmp,cnt,j,k,s,m,l,q:longint;
ch,h:string; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; procedure add(a,b:longint;c:string);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; function lca(x,y:longint):longint;
var d,i:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
for i:= to do
if d and (<<i)> then x:=f[x,i];
for i:= downto do
if f[x,i]<>f[y,i] then
begin
x:=f[x,i]; y:=f[y,i];
end;
if x=y then exit(x);
exit(f[x,]);
end; procedure build(i:longint;var p:longint);
begin
inc(cnt); t[cnt]:=t[p];
map[cnt]:=map[p];
p:=cnt; inc(t[p]);
if i<=l then build(i+,map[p,h[i]]);
end; procedure dfs(u:longint);
var e,v,i:longint;
begin
for i:= to do
begin
if dep[u]<(<<i) then break;
f[u,i]:=f[f[u,i-],i-];
end;
flag[u]:=; e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
dep[v]:=dep[u]+;
f[v,]:=u;
root[v]:=root[u];
h:=len[e]; l:=length(h);
build(,root[v]);
dfs(v);
end;
e:=next[e];
end;
end; function query(x,y,z,i:longint):longint;
begin
if i=l+ then exit(t[x]+t[y]-*t[z]);
exit(query(map[x,h[i]],map[y,h[i]],map[z,h[i]],i+));
end; begin
assign(input,'bzoj4477.in'); reset(input);
assign(output,'bzoj4477.out'); rewrite(output);
readln(n);
for i:= to n- do
begin
readln(ch);
k:=length(ch); x:=; y:=; h:='';
s:=;
for j:= to k do
begin
if ch[j]=' ' then begin inc(s); continue; end;
if s= then x:=x*+ord(ch[j])-ord('');
if s= then y:=y*+ord(ch[j])-ord('');
if s= then h:=h+ch[j];
end;
add(x,y,h);
add(y,x,h);
end;
dfs();
readln(m);
for i:= to m do
begin
readln(ch);
k:=length(ch); x:=; y:=; s:=; h:='';
for j:= to k do
begin
if ch[j]=' ' then begin inc(s); continue; end;
if s= then x:=x*+ord(ch[j])-ord('');
if s= then y:=y*+ord(ch[j])-ord('');
if s= then h:=h+ch[j];
end;
q:=lca(x,y);
l:=length(h);
writeln(query(root[x],root[y],root[q],));
end;
close(input);
close(output);
end.

【BZOJ4477】字符串树(可持久化Trie)的更多相关文章

  1. BZOJ4477[Jsoi2015]字符串树——可持久化trie树

    题目描述 萌萌买了一颗字符串树的种子,春天种下去以后夏天就能长出一棵很大的字符串树.字符串树很奇特,树枝上都密密麻麻写满了字符串,看上去很复杂的样子.[问题描述]字符串树本质上还是一棵树,即N个节点N ...

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

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

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

    传送门 Solution 复习下tire( ̄▽ ̄)/ 裸的可持久化tire,我用树剖求了下LCA Code #include <cstdio> #include <cstring&g ...

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

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

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

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

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

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

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

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

  8. P4585-[FJOI2015]火星商店问题【线段树,可持久化Trie】

    正题 题目链接:https://www.luogu.com.cn/problem/P4585 题目大意 \(n\)个集合,开始每个集合中有一个数字. 开启新的一天并且往集合\(s\)中插入数字\(v\ ...

  9. BZOJ4477 JSOI2015字符串树(可持久化trie)

    树上建可持久化trie即可,有点过于裸了.darkbzoj过了然而在bzoj一直wa,不知道哪有锅. #include<iostream> #include<cstdio> # ...

  10. 【BZOJ4477】[JSOI2015]字符串树(Trie树)

    [BZOJ4477][JSOI2015]字符串树(Trie树) 题面 BZOJ 题解 对于每个点维护其到根节点的所有字符串构成的\(Trie\),显然可持久化一下就很好写了. 然后每次询问就是\(u+ ...

随机推荐

  1. A1020 Tree Traversals (25 分)

    Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and i ...

  2. Python基础-Python注释

    一.什么是注释.特性 1.一段文字性的描述,通过注释,可以解释和明确Python代码的功能,并记录将来要修改的地方. 2.当程序处理时,Python解释器会自动忽略,不会被当做代码进行处理 二.注释的 ...

  3. Mysql 查询出某列字段 被包含于 条件数据中

    我们通常是使用  某条件  是否包含于 某列中   ,简单点 就是:select * from 表名 where  字段名 like '%条件数据%'; 现在说下   某列 被包含于 条件数据中 接下 ...

  4. Java - 网络

    要事为先,你如果想要在这个行业发展下去的话,实际上三角形的三个点在支撑着你发展,一个是技术.一个是管理(不是说管理别人,是管理你自己的时间,管理你自己的精力).还有一个就是沟通,注重这三点均衡的发展. ...

  5. python 时间加8小时后的时间

    eta_temp = one['arrival'].encode('utf-8') fd = datetime.datetime.strptime(eta_temp, "%Y-%m-%dT% ...

  6. asp.net 中 UpdataPanel 的使用注意点

    1. 在UpdataPanel 前必须加上asp:ScriptManager的控件,保证页面能够正常显示

  7. 二、Shell 变量

    Shell 变量 定义变量时,变量名不加美元符号($,PHP语言中变量需要),如: your_name="runoob.com" 注意,变量名和等号之间不能有空格,这可能和你熟悉的 ...

  8. 29.VUE学习之--键盘事件.键盘修饰符的实例讲解

    键盘事件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  9. 02 python网络爬虫《Http和Https协议》

    一.HTTP协议 1.概念: Http协议就是服务器(Server)和客户端(Client)之间进行数据交互(相互传输数据)的一种形式. 之间形成的特殊行话(黑话:(土匪)天王盖地虎,(我)宝塔镇河妖 ...

  10. batch-normalization为什么效果好

    batch-normalization为什么效果好 深度学习中 Batch Normalization为什么效果好? - 龙鹏-言有三的回答 - 知乎 https://www.zhihu.com/qu ...