[ZJOI2015]诸神眷顾的幻想乡
嘟嘟嘟
这题除了暴力我就不会了,感觉得用SAM,但是又和普通的SAM不一样。
看了题解才知道,这东西叫广义后缀自动机。
就是解决例如多个串的本质不同的子串的个数这样的问题。
做法就是每插入完一个串,就重新从根节点开始插入另一个字符串。(但一直只有一个SAM)
对于这道题,可以理解为在trie上建SAM。做法就是在trie上dfs,孩子节点从父亲节点在SAM中的位置插入,代码就是这样:
In void dfs(int now, int _f, int p)
{
p = S.insert(col[now], p);
for(int i = head[now], v; ~i; i = e[i].nxt)
if((v = e[i].to) ^ _f) dfs(v, now, p);
}
因为最多只有20个叶节点,所以我们以每一个叶节点为根,跑一边trie,同时往SAM里插入。这样一定包含了任意一条路径。因为一条路径可以看做从某一个根节点出发的路径的子路径。
最后在后缀自动机上求一下本质不同的子串数目就好了。
```c++
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans = 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, m, col[maxn], du[maxn];
struct Edge
{
int nxt, to;
}e[maxn << 1];
int head[maxn], ecnt = -1;
In void addEdge(int x, int y)
{
e[++ecnt] = (Edge){head[x], y};
head[x] = ecnt;
}
struct Sam
{
int cnt;
int tra[maxn * 40][11], len[maxn * 40], link[maxn * 40];
In void init() {link[cnt = 0] = -1;}
In int insert(int x, int las)
{
int now = ++cnt, p = las;
len[now] = len[las] + 1;
while(~p && !tra[p][x]) tra[p][x] = now, p = link[p];
if(p == -1) link[now] = 0;
else
{
int q = tra[p][x];
if(len[q] == len[p] + 1) link[now] = q;
else
{
int clo = ++cnt;
memcpy(tra[clo], tra[q], sizeof(tra[q]));
len[clo] = len[p] + 1;
link[clo] = link[q], link[q] = link[now] = clo;
while(~p && tra[p][x] == q) tra[p][x] = clo, p = link[p];
}
}
return now;
}
In ll calc()
{
ll ret = 0;
for(int i = 1; i <= cnt; ++i) ret += len[i] - len[link[i]];
return ret;
}
}S;
In void dfs(int now, int _f, int p)
{
p = S.insert(col[now], p);
for(int i = head[now], v; ~i; i = e[i].nxt)
if((v = e[i].to) ^ _f) dfs(v, now, p);
}
int main()
{
Mem(head, -1);
n = read(), m = read();
for(int i = 1; i <= n; ++i) col[i] = read();
for(int i = 1; i < n; ++i)
{
int x = read(), y = read();
addEdge(x, y), addEdge(y, x);
++du[x], ++du[y];
}
S.init();
for(int i = 1; i <= n; ++i) if(du[i] == 1) dfs(i, 0, 0);
write(S.calc()), enter;
return 0;
}
[ZJOI2015]诸神眷顾的幻想乡的更多相关文章
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1017 Solved: 599[Submit][S ...
- bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对[广义后缀自动机]的一些理解
先说一下对后缀自动机的理解,主要是对构造过程的理解. 构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢? 首先,子串$[0,L+1)$对应的状态不存 ...
- 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 974 Solved: 573 Descriptio ...
- 字符串(广义后缀自动机):BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 843 Solved: 510[Submit][St ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1124 Solved: 660[Submit][S ...
- 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
[BZOJ3926][Zjoi2015]诸神眷顾的幻想乡 Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝 ...
- bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机)
bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机) bzoj Luogu 题解时间 给你个无根trie树(你管这叫trie树?),问你选取一条 ...
- BZOJ3926:[ZJOI2015]诸神眷顾的幻想乡(广义SAM)
Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看. ...
- 【刷题】BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看. ...
- BZOJ3926 Zjoi2015 诸神眷顾的幻想乡【广义后缀自动机】
Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看. ...
随机推荐
- 02-Java中的对象和类
面向对象: 程序由对象构成,每个对象包含对用户公开的特定功能部分(public)和隐藏实现部分(private). 类: 构造对象的模板 对象: 对象的行为 --- 可以对对象施加的操作(方法) 对象 ...
- Python 集合符号
& 求交集 l 求并集 ^ 交叉补集 - 求差集 > = < =
- Async/Await是这样简化JavaScript代码的
译者按: 在Async/Await替代Promise的6个理由中,我们比较了两种不同的异步编程方法:Async/Await和Promise,这篇博客将通过示例代码介绍Async/Await是如何简化J ...
- JDK和Tomcat安装
JDK安装: 1,选择安装位置,其余默认安装,安装两次,一个是JDK,一个是JRE,安装在两个文件夹中. 2,配置环境变量: 1,新建一个变量,变量名:JAVA_HOME,变量值:C:\Program ...
- 前端学习 之 Bootstrap(二)
一.代码 内联代码:用<code>包裹,但是需要用<和>表示尖括号. 键盘输入:用<kbd>包裹表示键盘输入的内容. 多行代码:用<pre>包裹多行代码 ...
- HTML基础总结
HTML细化知识点总结 1.h1-h6标签 都是标题标签,定义一段话的标题,h1最大,依次递减,h6最小 标题标签的作用:让文本加粗显示 2. 段落标签:p标签 用来显示一段文本(图片),它会忽略源代 ...
- Android-TextView 控件常用属性以及基本用法
github地址:https://github.com/1165863642/TextViewDemo 前言 这是我第一次写博客,第一次的笔记,不足之处多谅解.开门见山,这一篇博客主要讲一下在Andr ...
- java垃圾回收机制GC
记得第一次总结java 的GC的时候,是刚开始在课堂上学习GC的时候,那时候许老师第一节java课 课后老师说同学们可以去深入理解一下java的GC机制: 但是是花费了三四个小时,翻看了<Thi ...
- Apache Linux下Apache安装步骤
Apache简介 Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,可以在大多数计算机操作系统中运行,由于其多平台和安全性被广 ...
- 【软件需求工程与建模 - 小组项目】第6周 - 成果展示3 - 软件设计规格说明书V4.1
成果展示3 - 软件设计规格说明书V4.1