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

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 790  Solved: 485
[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%的数据,除某两块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻

广义后缀自动机,思路很好

题目有一个关键条件:叶子的数量不超过20个。

以每一个叶子节点为根建一个Trie树,那么整棵树中的任意一条路径,都可以表示成某一个Trie树上一个点到它后代的一条路径。

那么,可以将这些Trie树合并成一个大Trie树,然后求这个大Trie树的字串数量。

这可以用广义的后缀自动机实现。

要注意在加入一个点的时候,如果a[p][x]&&mx[a[p][x]]==mx[p]+1,则不用新建节点,直接返回a[p][x]。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 100005
#define maxm 2000005
using namespace std;
int n,m,cnt,v[maxn],d[maxn],head[maxn];
ll ans;
struct edge_type{int next,to;}e[maxn*2];
struct sam
{int cnt,fa[maxm],mx[maxm],a[maxm][10];sam(){cnt=1;}   void solve(){F(i,1,cnt) ans+=mx[i]-mx[fa[i]];}int add(int p,int x){if (a[p][x]&&mx[a[p][x]]==mx[p]+1) return a[p][x];//广义后缀自动机,注意要判断mx int np=++cnt;mx[np]=mx[p]+1;while (p&&!a[p][x]) a[p][x]=np,p=fa[p];if (!p) fa[np]=1;else{int q=a[p][x];if (mx[p]+1==mx[q]) fa[np]=q;else{int nq=++cnt;mx[nq]=mx[p]+1;memcpy(a[nq],a[q],sizeof(a[q]));fa[nq]=fa[q];fa[np]=fa[q]=nq;while (a[p][x]==q) a[p][x]=nq,p=fa[p];}}return np;}
}sam;
inline int read()
{int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
inline void add_edge(int x,int y)
{e[++cnt]=(edge_type){head[x],y};head[x]=cnt;e[++cnt]=(edge_type){head[y],x};head[y]=cnt;
}
void dfs(int x,int fa,int p)
{int t=sam.add(p,v[x]);for(int i=head[x];i;i=e[i].next) if (e[i].to!=fa) dfs(e[i].to,x,t);
}
int main()
{n=read();m=read();F(i,1,n) v[i]=read();F(i,1,n-1){int x=read(),y=read();add_edge(x,y);d[x]++;d[y]++;}F(i,1,n) if (d[i]==1) dfs(i,0,1);sam.solve();printf("%lld\n",ans);return 0;
}

bzoj3926【ZJOI2015】诸神眷顾的幻想乡相关推荐

  1. [bzoj3926][Zjoi2015]诸神眷顾的幻想乡

    来自FallDream的博客,未经允许, 请勿转载,谢谢. 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情 ...

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

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

  3. [Zjoi2015]诸神眷顾的幻想乡

    [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 1537  Solved: 892 Description 幽香 ...

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

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec   Memory Limit: 512 MB Submit: 1381   Solved: 811 [ Subm ...

  5. bzoj 3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec   Memory Limit: 512 MB Submit: 1009   Solved: 596 [ Subm ...

  6. [ZJOI2015] 诸神眷顾的幻想乡

    P3256[ZJOI2015 Day1]诸神眷顾的幻想乡 时间限制 : 20000 MS   空间限制 : 524288 KB 问题描述 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生 ...

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

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

  8. [洛谷P3346][ZJOI2015]诸神眷顾的幻想乡

    题目大意:给你一棵$n$个点的树,最多有$20$个叶子节点,问共有几个不同的子串 题解:广义$SAM$,对每个叶子节点深搜一次,每个节点的$lst$设为这个节点当时的父亲,这样就可以时建出来的$SAM ...

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

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

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

    这道题首先要读明白题,就是说叶子节点不超过20个,那么我们就可以以每一个叶子节点为根建一个广义后缀自动机,这样就一定能表示出来所有的子串,然后统计一下答案就可以啦. (广义后缀自动机就是把好多串放到一 ...

最新文章

  1. 使用VC++6.0创建MFC对话框程序
  2. 华为100万部鸿蒙,2019年Q4发布 华为100万部鸿蒙OS手机已开测
  3. Vue3.0 + Ts 项目框架搭建四:配置 Svg-Icon、Icon图标
  4. linux常用分区大小,Linux基本知识点总结——硬盘分区及LVM
  5. html5font标签菜鸟教程,菜鸟教程
  6. 如何使用计算机自带的刻录软件,Win7系统自带光盘刻录功能如何使用?
  7. bzoj 4987 Tree
  8. 庄曜计算机应用作曲电子书阅读,庄曜计算机应用作曲的意义
  9. 订单流失总金额怎么算_微信新规下增长乏力,裂变到底该怎么做?
  10. 氨氮吹脱法脱与php有关系吗,吹脱法处理氨氮废水
  11. JavaScript自定义求和函数
  12. 单链表的逆置算法解析
  13. NUL 与 NULL
  14. 一个简单的C语言代码段,逻辑题
  15. Redis数据结构之——跳表skiplist
  16. python复利代码_使用Python进行复利
  17. linux学习——linux中文件属主、属组是什么意思
  18. adobe reader java_使用Adobe Reader控件结合Java实现PDF打印功能
  19. 一键屏蔽135、137、138、139、445危险端口和服务
  20. URL编码/解码详解

热门文章

  1. 通过Matlab计算拟合优度
  2. 【学习笔记】LaTeX中怎么添加文本高亮和给文字标红?
  3. AD(十八)PCB模块化设计+元件布局+布局优化
  4. download-git-repo 使用教程
  5. win10下Chrome弹出广告关闭
  6. linux安装软件imagemagick,linux下的ImageMagick安装方法
  7. 信息安全研究领域分类
  8. JAVA101本土精选,AcWing 101. 最高的牛JAVA
  9. android 多态按钮,PM撸代码之Android【武侠篇:封装、继承、多态】
  10. [转载]辜新星:时刻调整方向 找到人生的蓝海