3926: [Zjoi2015]诸神眷顾的幻想乡

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 1017  Solved: 599
[Submit][Status][Discuss]

Description

幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日。

粉丝们非常热情,自发组织表演了一系列节目给幽香看。幽香当然也非常高兴啦。 
这时幽香发现了一件非常有趣的事情,太阳花田有n块空地。在过去,幽香为了方便,在这n块空地之间修建了n-1条边将它们连通起来。也就是说,这n块空地形成了一个树的结构。 
有n个粉丝们来到了太阳花田上。为了表达对幽香生日的祝贺,他们选择了c中颜色的衣服,每种颜色恰好可以用一个0到c-1之间的整数来表示。并且每个人都站在一个空地上,每个空地上也只有一个人。这样整个太阳花田就花花绿绿了。幽香看到了,感觉也非常开心。 
粉丝们策划的一个节目是这样的,选中两个粉丝A和B(A和B可以相同),然后A所在的空地到B所在的空地的路径上的粉丝依次跳起来(包括端点),幽香就能看到一个长度为A到B之间路径上的所有粉丝的数目(包括A和B)的颜色序列。一开始大家打算让人一两个粉丝(注意:A,B和B,A是不同的,他们形成的序列刚好相反,比如红绿蓝和蓝绿红)都来一次,但是有人指出这样可能会出现一些一模一样的颜色序列,会导致审美疲劳。 
于是他们想要问题,在这个树上,一共有多少可能的不同的颜色序列(子串)幽香可以看到呢? 
太阳花田的结构比较特殊,只与一个空地相邻的空地数量不超过20个。 

Input

第一行两个正整数n,c。表示空地数量和颜色数量。

第二行有n个0到c-1之间,由空格隔开的整数,依次表示第i块空地上的粉丝的衣服颜色。(这里我们按照节点标号从小到大的顺序依次给出每块空地上粉丝的衣服颜色)。 
接下来n-1行,每行两个正整数u,v,表示有一条连接空地u和空地v的边。 

Output

一行,输出一个整数,表示答案。

Sample Input

7 3
0 2 1 2 1 0 0
1 2
3 4
3 5
4 6
5 7
2 5

Sample Output

30

HINT

对于所有数据,1<=n<=100000, 1<=c<=10。

对于15%的数据,n<=2000。 
另有5%的数据,所有空地都至多与两个空地相邻。 
另有5%的数据,除一块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻。 
另有5%的数据,除某两块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻

Source

[Submit][Status][Discuss]

OTZ 陈老师高深莫测的语文技巧……

通过对本短片小说最后一行的仔细观察,不难看出这块奇葩的田地形成了一棵至多只有20个叶子节点的树(然而我看了半天都没发现)。

所以从这至多20个节点出发,向根DFS,建立广义自动机,那么树上的每一条路径都是一个可被SAM接受的子串,答案即为SAM中不同的子串个数,累加最长路差值即可。

 #include <bits/stdc++.h>

 /* MYSCANNER */

 #define siz 1024

 inline int get_c(void)
{
static char buf[siz];
static char *head = buf + siz;
static char *tail = buf + siz; if (head == tail)
fread(head = buf, , siz, stdin); return *head++;
} inline int get_i(void)
{
register int ret = ;
register int neg = false;
register int bit = get_c(); for (; bit < ; bit = get_c())
if (bit == '-')neg ^= true; for (; bit > ; bit = get_c())
ret = ret * + bit - ''; return neg ? -ret : ret;
} const int maxn = ; /* AUTOMATON */ int tail = ;
int root[maxn];
int step[maxn];
int fail[maxn];
int next[maxn][]; inline int extend(int p, int c)
{
if (next[p][c] && step[next[p][c]] == step[p] + )
return next[p][c];
int t = tail++;
step[t] = step[p] + ;
while (p && !next[p][c])
next[p][c] = t, p = fail[p];
if (p)
{
int q = next[p][c];
if (step[q] == step[p] + )
fail[t] = q;
else
{
int k = tail++;
fail[k] = fail[q];
fail[q] = fail[t] = k;
step[k] = step[p] + ;
memcpy(next[k], next[q], sizeof(next[k]));
while (p && next[p][c] == q)
next[p][c] = k, p = fail[p];
}
}
else
fail[t] = ;
return t;
} /* GRAPH */ int n;
int m;
int tot;
int hd[maxn];
int nt[maxn];
int to[maxn];
int cnt[maxn];
int col[maxn];
int vis[maxn];
int que[maxn]; inline void addEdge(int x, int y)
{
nt[++tot] = hd[x]; to[tot] = y; hd[x] = tot;
nt[++tot] = hd[y]; to[tot] = x; hd[y] = tot;
} void DFS(int u, int f)
{
root[u] = extend(root[f], col[u]);
for (int i = hd[u]; i; i = nt[i])
if (to[i] != f)DFS(to[i], u);
} /* MAIN FUNC */ signed main(void)
{
n = get_i();
m = get_i(); for (int i = ; i <= n; ++i)
col[i] = get_i(); for (int i = ; i < n; ++i)
{
int x = get_i();
int y = get_i();
addEdge(x, y);
++cnt[x];
++cnt[y];
} root[] = tail++; for (int i = ; i <= n; ++i)
if (cnt[i] == )DFS(i, ); long long ans = 0LL; int head = , tail = ; que[tail++] = ; while (head != tail)
{
int t = que[head++];
if (t != )
ans += step[t] - step[fail[t]];
for (int i = ; i < m; ++i)
if (next[t][i] && !vis[next[t][i]])
vis[next[t][i]] = , que[tail++] = next[t][i];
} printf("%lld\n", ans);
}

@Author: YouSiki

BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡的更多相关文章

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

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 843  Solved: 510[Submit][St ...

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

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

  3. bzoj 3926 [Zjoi2015]诸神眷顾的幻想乡(SAM)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3926   [题意]   给定一棵树,每个节点都有相应的颜色,且保证叶子数不超过20,问 ...

  4. ●BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3926题解&&代码: 后缀自动机,Trie树 如果以每个叶子为根,所有的子串一 ...

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

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

  6. 【刷题】BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡

    Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看. ...

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

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

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

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

  9. bzoj 3926: [Zjoi2015]诸神眷顾的幻想乡【SAM】

    有一个显然的性质就是每个串一定在某个叶子为根的树中是一条直的链 然后因为SAM里是不会有相同状态的,所以以每个叶子为根dfs一遍,并且动态构造SAM(这里的节点u的last指向父亲),最后统计答案就是 ...

随机推荐

  1. iOS开发工程师面试题(二)

    1.手写冒泡跟插入排序 冒泡排序来源于生活常识,相当于把数组竖起来,轻的向上,重的向下.void bubbleSort(int[] unsorted) { ; i < unsorted.Leng ...

  2. HTML5-02 元素

    概述 HTML 文档主要由元素组成,且主要分为两大部分:头部 和 主体.如图: 头部 概述 <head> 元素包含了所有的头部标签.<head> 元素中通常包含脚本(scrip ...

  3. 1-学习前言&C语言概述

    [C语言]01-学习前言&C语言概述 参考自 http://www.cnblogs.com/mjios/archive/2013/03/12/2956508.html#label2 C语言是我 ...

  4. RMAN异机还原遭遇ORA-19698错误案例

    实验环境:               操作系统    :Oracle Linux Server release 5.7 64 bit               数据库版本:Oracle Datab ...

  5. C++基础——模拟事务 (1)COMMAND模式

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  6. 【CSS】其他CSS属性和特性

    1. 设置元素的颜色和透明度 前面有介绍CSS颜色的各种用法,如 background-color属性.boder-color属性等.还有另外两个与颜色有关的属性. 1.1 设置前景色 color属性 ...

  7. mysql表复制和修改部分字段

    今天在工作中,需要造大量的加数据,1000多条数据如果都是手工输入的话,那么我今天不要干别的了,就造吧! 当时手工操作重复的事情,对程序员来说,是一件很丢人的事情,所以就上网查了一下,需要用到两个知识 ...

  8. jdbc执行Statement接口的步骤

    jdbc执行Statement接口的步骤如下: 1)驱动注册程序: Class.forName(com.mysql.jdbc.Driver); 2)获取连接对象: Connection conn = ...

  9. Java.utils.Collections学习

    阅读类库代码是有意义的,尤其是Java集合类框架以及算法Collections Arrays都是值得阅读的, 一来可以减少新手程序员的编码的工作量,二来,对于常见的需求,程序员应该先找下是否有现成的类 ...

  10. codevs 2495 水叮当的舞步

    题目链接:水叮当的舞步 我现在开始发题目链接了(主要还是因为懒得整理题面)-- 这道题一开始是看到MashiroSky在写,于是我也开始写这道题了(说白了就是狙击他)-- 这道题看到这么小的范围当然给 ...