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%的数据,除某两块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻

Solution

广义$SAM$,也就是给一个$Trie$建$SAM$。具体操作很简单,就是$DFS$一下$Trie$树,每次将一个字符插入$SAM$的时候,将$SAM$的$last$记为这个字符在$Trie$树上的父亲的$np$就可以了。

由于一种字符串只能做出一次贡献,所以答案为$ans=\sum step[i]-step[fa[i]]$

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#define N (2000009)
#define M (100009)
#define LL long long
using namespace std; struct Edge{int to,next;}edge[M<<];
int head[M],num_edge;
int n,m,u,v,a[M],Ind[M]; void add(int u,int v)
{
edge[++num_edge].to=v;
edge[num_edge].next=head[u];
head[u]=num_edge;
} struct SAM
{
int son[N][],fa[N],step[N],wt[N],od[N];
int p,q,np,nq,cnt;
SAM(){cnt=;} int Insert(int last,int x)
{
p=last; np=++cnt; step[np]=step[p]+;
while (!son[p][x] && p) son[p][x]=np, p=fa[p];
if (!p) fa[np]=;
else
{
q=son[p][x];
if (step[p]+==step[q]) fa[np]=q;
else
{
nq=++cnt; step[nq]=step[p]+;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
while (son[p][x]==q) son[p][x]=nq, p=fa[p];
}
}
return np;
}
void Calc()
{
LL ans=;
for (int i=; i<=cnt; ++i)
ans+=(LL)(step[i]-step[fa[i]]);
printf("%lld\n",ans);
}
}SAM; void DFS(int x,int fa,int pre)
{
int tmp=SAM.Insert(pre,a[x]);
for (int i=head[x]; i; i=edge[i].next)
if (edge[i].to!=fa) DFS(edge[i].to,x,tmp);
} int main()
{
scanf("%d%d",&n,&m);
for (int i=; i<=n; ++i)
scanf("%d",&a[i]);
for (int i=; i<=n-; ++i)
{
scanf("%d%d",&u,&v);
add(u,v); add(v,u);
Ind[u]++; Ind[v]++;
}
for (int i=; i<=n; ++i)
if (Ind[i]==) DFS(i,-,);
SAM.Calc();
}

BZOJ3926:[ZJOI2015]诸神眷顾的幻想乡(广义SAM)的更多相关文章

  1. BZOJ3926 [Zjoi2015]诸神眷顾的幻想乡 字符串 SAM

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3926.html 题目传送门 - BZOJ3926 题意 给定一个有 $n$ 个节点,最多只有 $20$ ...

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

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

  3. Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡 广义SAM 后缀自动机

    题目链接 \(Click\) \(Here\) 真的是好题啊-不过在说做法之前先强调几个自己总是掉的坑点. 更新节点永远记不住往上跳\(p = fa[p]\) 新建节点永远记不住\(len[y] = ...

  4. bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对[广义后缀自动机]的一些理解

    先说一下对后缀自动机的理解,主要是对构造过程的理解. 构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢? 首先,子串$[0,L+1)$对应的状态不存 ...

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

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

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

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

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

    日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常高兴啦.  这时幽香发现了一件非常有趣的事情,太阳花田有n块空地.在过去 ...

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

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

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

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

随机推荐

  1. Form身份验证

    Forms身份验证Web.config<system.web><authentication mode="Forms">            <fo ...

  2. Web开发 学习积累20161018

    项目 一.项目做的是什么 业务逻辑 -> 增删改查 二.什么是面向对象编程,它有哪些好处 oop:object oriented programming <>核心思想:使用人类思考问 ...

  3. Git建立独立分支

    前言 在码云建立git项目后默认分支是master, 这里如果直接在码云新建分支, 会指定默认分支; 所以通过git 命令git checkout --orphan 新分支名 创建独立分支 创建 创建 ...

  4. The configuration section 'system.serviceModel' cannot be read because it is missing a section decla

    将Asp.Net 2.0的Web Site搭建在IIS7(7.5)上时,运行出现500.19错误, 错误提示为 The configuration section 'system.serviceMod ...

  5. 由上一个血案引发的关于property和attribute关系的思考

    boss说,学习要刨根问底. 好的,开刨. 一.property和attribute在英语里有什么区别 看似没有区别.但其实大神说: property是 物体本身自带属性,不能改变的(一旦改了就是另外 ...

  6. DOM基础操作(二)

    插入操作 1.appendChild(child); 这个是父级调用的方法,它会将child元素插入到父级里面,而且是放到逻辑后面的位置上.   div.appendChild(comment);   ...

  7. 浏览器好玩的的 console.log

    现在很多网站,你在访问他页面的时候, 你要查看 console 的话, 看到有文章介绍的,一定想知道是怎么展示来的吧 如 baidu 的 你懂的,其实很简单,代码如下, console 输出下就行 c ...

  8. MyEclipse 2017/2018 安装与破解 图文教程

    SSM 框架-02-MyEclipse 2017/2018 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEc ...

  9. Java快速入门-02-基础篇

    Java快速入门-02-基础篇 上一篇应该已经让0基础的人对 Java 有了一些了解,接一篇更进一步 使用 Eclipse 快捷键 这个老师一般都经常提,但是自己不容易记住,慢慢熟练 快捷键 快捷键作 ...

  10. android资源的诡异问题

    最近,新开发版本,正在处于扫BUG的阶段. 发现一个比较诡异的问题,一个控件的颜色,背景色与预先设定的值,发生不一致.其他的类型的控件有同样的设置,但是现实结果正常. 今天,专门解决这个问题. 经过各 ...