题目:

题目在这里

思路&做法:

参考的题解

既然只有\(20\)个叶子节点, 那么可以从每个叶子节点往上建一颗\(trie\)树, 然后合并成一棵大的\(trie\)树, 然后构建广义后缀自动机。

\((\) 实现起来就是dfs时把节点上的颜色加进广义后缀自动机\()\)

再然后就统计一下就可以了\((ans += len[x] - len[fail[x])\)

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cstring> using namespace std; const int N = 2000010; long long Ans; struct Suffix_Automaton
{ int nxt[N][10], fail[N], sz;
int len[N];
int root; Suffix_Automaton() { } inline int newnode(int l)
{ memset(nxt[sz], 0, sizeof(nxt[sz]));
fail[sz] = 0;
len[sz] = l;
return sz++;
} inline void init()
{ sz = 1;
root = newnode(0);
} int add(int c, int last)
{ if(nxt[last][c])
{ int p = last, q = nxt[p][c];
if(len[q] == len[p]+1)
return q;
else
{ int u = newnode(len[p] + 1);
for(int i=0; i<10; i++) nxt[u][i] = nxt[q][i];
fail[u] = fail[q];
fail[q] = u;
while(nxt[p][c] == q)
{ nxt[p][c] = u;
p = fail[p];
}
return u;
}
}
else
{ int now = newnode(len[last] + 1);
int p = last;
while(p && !nxt[p][c])
{ nxt[p][c] = now;
p = fail[p];
}
if(!p) fail[now] = root;
else
{ int q = nxt[p][c];
if(len[q] == len[p]+1)
fail[now] = q;
else
{ int u = newnode(len[p] + 1);
for(int i=0; i<10; i++) nxt[u][i] = nxt[q][i];
fail[u] = fail[q];
fail[q] = fail[now] = u;
while(nxt[p][c] == q)
{ nxt[p][c] = u;
p = fail[p];
}
}
}
Ans += (long long) (len[now] - len[fail[now]]);
return now;
}
}
} tzw; int color[N]; int r[N]; struct edge
{ int from, to;
edge() { }
edge(int _1, int _2):from(_1), to(_2) { }
} edges[2*N];
int head[N], nxt[2*N], tot; inline void init()
{ memset(head, -1, sizeof(head));
tot = 0;
} inline void Add_Edge(int x, int y)
{ edges[tot] = edge(x, y);
nxt[tot] = head[x];
head[x] = tot++;
edges[tot] = edge(y, x);
nxt[tot] = head[y];
head[y] = tot++;
} void dfs(int x, int fa, int last)
{ last = tzw.add(color[x], last);
for(int i=head[x]; ~i; i=nxt[i])
{ edge & e = edges[i];
if(e.to != fa)
dfs(e.to, x, last);
}
} int main()
{ int n, m;
scanf("%d %d", &n, &m);
for(int i=1; i<=n; i++)
scanf("%d", &color[i]);
tzw.init();
init();
for(int i=1; i<n; i++)
{ int x, y;
scanf("%d %d", &x, &y);
Add_Edge(x, y);
r[x]++, r[y]++;
}
for(int i=1; i<=n; i++)
if(r[i] == 1) dfs(i, 0, tzw.root);
printf("%lld\n", Ans);
return 0;
}

【BZOJ3926】【ZJOI2015】诸神眷顾的幻想乡 广义后缀自动机的更多相关文章

  1. bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机模板

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

  2. 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机

    [BZOJ3926][Zjoi2015]诸神眷顾的幻想乡 Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝 ...

  3. BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1124  Solved: 660[Submit][S ...

  4. BZOJ.3926.[ZJOI2015]诸神眷顾的幻想乡(广义后缀自动机)

    题目链接 要对多个串同时建立SAM,有两种方法: 1.将所有串拼起来,中间用分隔符隔开,插入字符正常插入即可. 2.在这些串的Trie上建SAM.实际上并不需要建Trie,还是只需要正常插入(因为本来 ...

  5. 洛谷P3346 [ZJOI2015]诸神眷顾的幻想乡(广义后缀自动机)

    题意 题目链接 Sol 广义SAM的板子题. 首先叶子节点不超过20,那么可以直接对每个叶子节点为根的子树插入到广义SAM中. 因为所有合法的答案一定是某个叶子节点为根的树上的一条链,因此这样可以统计 ...

  6. BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串

    https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比 ...

  7. BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡 ——广义后缀自动机

    神奇的性质,叶子节点不超过20个. 然后把这些节点提出来构成一颗新树,那么这些树恰好包含了所有的情况. 所以直接广义后缀自动机. 然后统计本质不同的字符串就很简单显然了. #include <c ...

  8. [ZJOI2015]诸神眷顾的幻想乡 广义后缀自动机_DFS_语文题

    才知道题目中是只有20个叶子节点的意思QAQ.... 这次的广义后缀自动机只是将 last 设为 1, 并重新插入. 相比于正统的写法,比较浪费空间. Code: #include <cstdi ...

  9. BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机 多串)

    因为任何一条路径都可以看做某两个叶子节点之间路径的一部分,然后分别把20个叶节点当作根,把整棵树看作trie树,那么一条路径就能看作是从根到某个点这一条路的后缀,构建SAM就能维护不同子串的个数了. ...

  10. 【BZOJ3926】诸神眷顾的幻想乡(后缀自动机)

    [BZOJ3926]诸神眷顾的幻想乡(后缀自动机) 题面 BZOJ 题解 广义后缀自动机啦 求多个串的不同子串个数? 当然是后缀自动机,最后只要把\(longest-parent.longest\)求 ...

随机推荐

  1. SQL Server 一个简单的游标

    先看一下原表: DECLARE @id INT; DECLARE @name NVARCHAR(100); DECLARE c_department CURSOR FOR SELECT StuID, ...

  2. SQL语言入门

    内容来源:唐成. PostgreSQL修炼之道[M]. 机械工业出版社, 2015. 此书购买链接:京东 亚马逊 SQL(Structured Query Language) 结构化查询语言 1. 语 ...

  3. OpenCV边缘检测的详细参数调节

    1. findCountours 转载于http://blog.sina.com.cn/s/blog_7155fb1a0101a90h.html findContours函数,这个函数的原型为: &l ...

  4. PAT_A1148#Werewolf - Simple Version

    Source: PAT 1148 Werewolf - Simple Version (20 分) Description: Werewolf(狼人杀) is a game in which the ...

  5. Shell 在手分析服务器日志不愁

    转自:https://wujunze.com/server_logs_analysis.jsp 自己的小网站跑在阿里云的ECS上面,偶尔也去分析分析自己网站服务器日志,看看网站的访问量.看看有没有骇客 ...

  6. void 0 与 undefined

    偶然看到一个问题:为什么有的编程规范要求用 void 0 代替 undefined? 如果不知道这个答案的小伙伴,第一反应就要问void 0是什么鬼? void 0 void是JavaScript的一 ...

  7. C语言开发框架、printf(day02)

    C语言里包含以.c作为扩展名的文件,这种 文件叫源文件.C语言程序的绝大部分内容 应该记录在源文件里. C语言里还包括以.h作为扩展名的文件,这种 文件叫头文件. C语言程序里可以直接使用数字和加减乘 ...

  8. 1.VMware虚拟机的安装

    1.找到安装软件 2.使用如下操作安装 3.选择接受协议 4.修改安装目录 5.如果上一步有修改,此步骤不用改路径 7.安装后创建桌面快捷方式 8.安装成功可以看到桌面上有快捷方式图标 安装结束 声明 ...

  9. Netty学习总结(2)——Netty的高性能架构之道

    Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用 ...

  10. CodeForces - 274A - k-Multiple Free Set

    先上题目 k-Multiple Free Set time limit per test 2 seconds memory limit per test 256 megabytes input sta ...