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

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 1124  Solved: 660
[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

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

HINT

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


我去真醉了.....SAM直接复制上一题,然后上一题只有01,然后就悲剧的找了好长时间SAM哪里出问题了.......
 
本题的重点是对20个Trie建SAM,方法是dfs中保存last然后建就行了.......
好吧其实我想了好长时间这样为什么对,然后看到了abclzr神犇写的才想明白 http://www.cnblogs.com/abclzr/p/6288505.html
 
直接对Trie建SAM与原本一个串建SAM唯一的不同是last可能已经有--c-->q了,我们有两种选择来处理
如果t[q].val==t[last].val+1
第一种是直接不管,这样t[np].par=q,np和q可以看作一个点,不受影响
第二种是管,直接让last走到q,也没关系
如果t[q].val!=t[last].val+1
这时会新建节点nq,然后t[q].par=t[np].par=nq 注意np和nq的Right是一样的(因为本来last有--c-->这个转移啊,所有的r都可以r+1),但没关系,依旧看作一个点
 
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N=2e5+;
typedef long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,c,s[N];
struct node{
int ch[],par,val;
}t[N*];
int sz=,root=;
void extend(int c,int &last){
int q=t[last].ch[c];if(q&&t[q].val==t[last].val+) {last=q;return;}
int p=last,np=++sz;
t[np].val=t[p].val+;
for(;p&&!t[p].ch[c];p=t[p].par) t[p].ch[c]=np;
if(!p) t[np].par=root;
else{
int q=t[p].ch[c];
if(t[q].val==t[p].val+) t[np].par=q;
else{
int nq=++sz;
t[nq]=t[q];t[nq].val=t[p].val+;
t[q].par=t[np].par=nq;
for(;p&&t[p].ch[c]==q;p=t[p].par) t[p].ch[c]=nq;
}
}
last=np;
} struct edge{
int v,ne;
}e[N];
int cnt,h[N],de[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
de[u]++;de[v]++;
}
void dfs(int u,int fa,int last){
extend(s[u],last);
for(int i=h[u];i;i=e[i].ne) if(e[i].v!=fa) dfs(e[i].v,u,last);
}
void solve(){
for(int i=;i<=n;i++) if(de[i]==) dfs(i,,root);
ll ans=;
for(int i=;i<=sz;i++) ans+=t[i].val-t[t[i].par].val;
printf("%lld",ans);
}
int main(){
freopen("in","r",stdin);
n=read();c=read();
for(int i=;i<=n;i++) s[i]=read();
for(int i=;i<=n-;i++) ins(read(),read());
solve();
}
 

BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]的更多相关文章

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

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

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

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

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

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

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

    因为任何一条路径都可以看做某两个叶子节点之间路径的一部分,然后分别把20个叶节点当作根,把整棵树看作trie树,那么一条路径就能看作是从根到某个点这一条路的后缀,构建SAM就能维护不同子串的个数了. ...

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

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

  6. BZOJ 3926: [Zjoi20150]诸神眷顾的幻想乡(后缀自动机)

    被这道题坑了= =只与一个空地相连的空地不超过20个只与一个空地相连的空地不超过20个 因为很重要所以说两遍 就是说儿子节点最多只有20个 把这20个节点作为根遍历一遍所得到的tire所得到的所有不同 ...

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

    题意 题目链接 Sol 广义SAM的板子题. 首先叶子节点不超过20,那么可以直接对每个叶子节点为根的子树插入到广义SAM中. 因为所有合法的答案一定是某个叶子节点为根的树上的一条链,因此这样可以统计 ...

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

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

  9. [ZJOI2015]诸神眷顾的幻想乡 广义后缀自动机_DFS_语文题

    才知道题目中是只有20个叶子节点的意思QAQ.... 这次的广义后缀自动机只是将 last 设为 1, 并重新插入. 相比于正统的写法,比较浪费空间. Code: #include <cstdi ...

随机推荐

  1. hbmy周赛1--D

    D - Toy Cars Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submi ...

  2. linux下各文件夹的结构说明及用途介绍

    linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令.   /dev:设备特殊文件.   /etc:系统管理和配置文件.   /etc/rc.d:启动的配 置文件和脚本.   /ho ...

  3. Spring框架学习笔记(1)——HelloWorld

    1.创建一个新的项目,并添加Spring框架 2.创建HelloWorld.java package com.broadtext.beans.helloworld; public class Hell ...

  4. JXLS 2.4.0系列教程(四)——多sheet是怎么做到的

    注:本文代码在第一篇文章基础上修改而成,请务必先阅读第一篇文章. http://www.cnblogs.com/foxlee1024/p/7616987.html 本文也不会过多的讲解模板中遍历表达式 ...

  5. ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package

    目前在学习ASP.NET CORE MVC中,今天看到微软在ASP.NET CORE MVC 2.0中又恢复了允许开发人员引用第三方DLL程序集的功能,感到甚是高兴!于是我急忙写了个Demo想试试,我 ...

  6. python动态类型

    在python中,省去了变量声明的过程,在引用变量时,往往一个简单的赋值语句就同时完成了,声明变量类型,变量定义和关联的过程,那么python的变量到底是怎样完成定义的呢? 动态类型 python使用 ...

  7. nginx https配置后无法访问,可能防火墙在捣鬼

    同事发现nginx配置后https 无法访问,我帮忙解决的时候从以下出发点 1.防火墙未开放443端口 2.配置出错 1 2 3 于是就 netstat -anp 查看防火墙开的端口 发现已经在监听了 ...

  8. libpng+VS2012(VS2015)的使用

    OpenCV保存PNG图像底层调用的就是libpng库,简要说一下libPNG库的单独使用. 1.首先需要下载两个库,一个是libpng,一个是zlib libpng库下载地址:http://www. ...

  9. jquery ui-----弹出窗口 dialog

    jquery ui 提供了强大的dialog功能,基本能满足开发的功能. 先上一个简单的例子: [代码] <script> $(function() {   $( "#dialo ...

  10. Java常用的框架

    一.SpringMVC http://blog.csdn.net/evankaka/article/details/45501811 Spring Web MVC是一种基于Java的实现了Web MV ...