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 \leq n \leq 100000\) , \(1 \leq c \leq 10\)。

对于 \(15%\) 的数据,\(n \leq 2000\)。

另有 \(5%\) 的数据,所有空地都至多与两个空地相邻。

另有 \(5%\) 的数据,除一块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻。

另有 \(5%\) 的数据,除某两块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻。


想法

小数据其实已经提示做法了……

由题意,叶子节点不超过 \(20\) 个。

经过手玩发现,分别以每个叶子节点为根,走到所有点,路径覆盖了所有 点对 之间的路径。

要求本质不同的子串数,这就是广义后缀自动机的模板题了。

啥叫广义后缀自动机?

就是多个字符串可以建在同一个后缀自动机上。

具体方法是,改 \(last\) 的位置。

如插入完一个字符串,再插一个新串时,\(last\) 改到 \(root\)


代码

调了半天,发现 \(insert\) 里少写了一种情况 \(orz...\)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring> using namespace std; int read(){
char ch=getchar();
int x=0;
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x;
} const int N = 100005;
typedef long long ll; struct node{
int v;
node *nxt;
}pool[N*2],*h[N];
int cnt;
void addedge(int u,int v){
node *p=&pool[++cnt],*q=&pool[++cnt];
p->v=v;p->nxt=h[u];h[u]=p;
q->v=u;q->nxt=h[v];h[v]=q;
} int n,C;
int col[N],deg[N]; struct trie{
trie *ch[11],*pa;
int len;
}pool2[N*40],*root,*pos[N],*last;
int cnt2;
void insert(int c){
trie *p=last,*cur=&pool2[++cnt2];
cur->len=p->len+1;
for(;p && !p->ch[c];p=p->pa) p->ch[c]=cur;
if(!p) cur->pa=root;
else {
trie *q=p->ch[c],*nq;
if(q->len!=p->len+1){
nq=&pool2[++cnt2];
for(int i=0;i<C;i++) nq->ch[i]=q->ch[i];
nq->len=p->len+1;
nq->pa=q->pa;
q->pa=cur->pa=nq;
for(;p && p->ch[c]==q;p=p->pa) p->ch[c]=nq;
}
else cur->pa=q;
}
last=cur;
} int vis[N];
void dfs(int u){
int v;
vis[u]=1;
for(node *p=h[u];p;p=p->nxt){
if(vis[v=p->v]) continue;
last=pos[u];
insert(col[v]);
pos[v]=last;
dfs(v);
}
} ll dp[N*40];
ll count(trie *p){
if(dp[p-pool2]!=-1) return dp[p-pool2];
dp[p-pool2]=1;
for(int i=0;i<C;i++)
if(p->ch[i]) dp[p-pool2]+=count(p->ch[i]);
return dp[p-pool2];
} int main()
{
int u,v;
n=read(); C=read();
for(int i=1;i<=n;i++) col[i]=read();
for(int i=1;i<n;i++){
u=read(); v=read();
addedge(u,v);
deg[u]++; deg[v]++;
} root=&pool2[++cnt2];
for(int i=1;i<=n;i++){
if(deg[i]!=1) continue;
memset(vis,0,sizeof(vis));
last=root;
insert(col[i]);
pos[i]=last;
dfs(i);
} memset(dp,-1,sizeof(dp));
printf("%lld\n",count(root)-1); return 0;
}

[bzoj3926] [loj2137] [Zjoi2015] 诸神眷顾的幻想乡的更多相关文章

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

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

  2. bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机)

    bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机) bzoj Luogu 题解时间 给你个无根trie树(你管这叫trie树?),问你选取一条 ...

  3. 【bzoj3926】 Zjoi2015—诸神眷顾的幻想乡

    http://www.lydsy.com/JudgeOnline/problem.php?id=3926 (题目链接) 题意 给出一棵树,每个节点有一个编号,范围在${[0,9]}$.一个序列是指树上 ...

  4. BZOJ3926:[ZJOI2015]诸神眷顾的幻想乡——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3926 https://www.luogu.org/problemnew/show/P3346 幽香 ...

  5. 【bzoj3926】[Zjoi2015]诸神眷顾的幻想乡

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

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

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

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

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

  8. 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 974  Solved: 573 Descriptio ...

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

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

随机推荐

  1. win10 uwp 好看的时间选择控件

    本文告诉大家我找到的好看的时间选择控件 先给大家看一下图,然后就知道我说的是什么 首先需要安装 Nuget ,搜索 DeanChalk.UWP.TimePicker 或输入Install-Packag ...

  2. linux 安装一个共享的处理者

    共享中断通过 request_irq 来安装就像不共享的一样, 但是有 2 个不同: SA_SHIRQ 位必须在 flags 参数中指定, 当请求中断时. dev_id 参数必须是独特的. 任何模块地 ...

  3. Maven 运行 tomcat:run 时出现 Unable to compile class for JSP...

    近来无事便去看了看神奇的 Maven , 但写第一个 Hello,World 就非常不友好的怼给我一个 500, 很是郁闷; 开发环境: JDK1.8, Maven 3.5 项目目录: \maven_ ...

  4. C语言动态内存

    动态分配内存的概述 在数组一章中,介绍过数组的长度是预先定义好的,在整个程序中固定不变,但是在实际的编程中,往往会发生这种情况,即所需内存空间取决于实际输入的数据,而无法预先确定.为了解决上述问题,c ...

  5. 解决netcore在docker容器中连接oracle报错(timezone region not found)

    错误提示: timezone region not found错误原因:docker 容器内时区不是 CST 导致解决办法:1.在dockerfile 中增加一下命令ENV TZ=Asia/Shang ...

  6. POJ 2976 Dropping tests [二分]

    1.题意:同poj3111,给出一组N个有价值a,重量b的物品,问去除K个之后,剩下的物品的平均值最大能取到多少? 2.分析:二分平均值,注意是去除K个,也就是选取N-K个 3.代码: # inclu ...

  7. bug(一)环境问题

    1.项目开发完成,部署到服务器进行测试,遇到一个问题: 同样的接口,同样的数据库表,同样的功能,得到不同的查询结果 具体如下图: 可以看到一个是有值的,一个是无值的,断点调试会发现所以的状态都是对的, ...

  8. java中发送http请求的方法

    package org.jeecgframework.test.demo; import java.io.BufferedReader; import java.io.FileOutputStream ...

  9. python之子类继承父类时进行初始化的一些问题

    直接看代码: class Person: def __init__(self): self.name = "jack" class Student(Person): def __i ...

  10. MySQL中文乱码 - window环境

    MySQL中文乱码 window环境 Linux环境请参考这篇文章:[https://www.cnblogs.com/hankleo/p/9695842.html]: 查看及修改字符集sql --查看 ...