题目:

题目在这里

思路&做法:

参考的题解

既然只有\(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. Microsoft SQL Server数据库学习(一)

    数据库的分类: 1.关系型数据库: 数据库名称 类型 公司 平台 Access 小型数据库 微软 Windows Mysql 小型数据库 AB--sun--甲骨文 Windows/linux/mac ...

  2. 【Linux】Ubuntu输入法不能开机自启的解决方法

    操作系统:Ubuntu Kylin 16.10 自从操作系统安装了搜狗输入法以后,每次重启电脑都需要手动启动Fcitx,才能启动搜狗输入法.下面给大家介绍输入法开机自启的解决方法: 操作系统的用户家目 ...

  3. 深圳面试一周记录——.NET(B/S)开发

    个人简单信息:2011年毕业,最高学历大专,最近一份工作在广州:有做架构设计经验,有一年的带团队(10人左右)经验:互联网和行业软件公司都待过. 为免不必要的争论,本文说地址的就不说公司行业,说公司行 ...

  4. servlet_获取初始化参数

    在web.xml的<servlet>标签中增添 <init-param> <param-name>XXX</param-name> <param- ...

  5. JSP状态管理_1_Cookie

    http协议的无状态性:当浏览器发送请求飞服务器时,服务器相应客户端请求:但当同一个浏览器再次发送请求给浏览器时,服务器并不知道它就是刚才那个客户端. 保存用户状态的两大机制:Session,Cook ...

  6. 浅谈Web缓存-缓存的实现过程详解

    在前端开发中,性能一直都是被大家所重视的一点,然而判断一个网站的性能最直观的就是看网页打开的速度.其中提高网页反应速度的一个方式就是使用缓存.一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并 ...

  7. 将 GNOME 默认的界面切换动画功能关闭

    gsettings set org.gnome.desktop.interface enable-animations false

  8. java将父类所有的属性COPY到子类中

    public class FatherToChildUtils { /* * 将父类所有的属性COPY到子类中. * 类定义中child一定要extends father: * 而且child和fat ...

  9. 【udacity】机器学习-knn最近邻算法

    Evernote Export 1.基于实例的学习介绍 不同级别的学习,去除所有的数据点(xi​,yi​),然后放入一个数据库中,下次直接提取数据 但是这样的实现方法将不能进行泛化,这种方式只能简单的 ...

  10. iphone 事件冒泡规则

    今天碰到的一个比较烦人的问题是,在body上添加事件处理函数,发现在iphone上怎么也没办法触发事件,找了半天,发现iPhone处理冒泡事件的规则: 1.点击某个元素: 2.如果这个元素上没有处理该 ...