后缀自动机扩展到树形结构上。

先建出大的Trie,然后我们得到了一棵Trie树,对于树上的每个节点,保存一个后缀自动机从根走它代表的字符串后到达的节点,每次其儿子就从父亲的这个节点开始扩展。

 /**************************************************************
Problem: 3926
User: idy002
Language: C++
Result: Accepted
Time:4320 ms
Memory:460976 kb
****************************************************************/ #include <cstdio>
#include <cassert>
#include <cstring>
#include <algorithm>
#define N 100010
#define ST 3000100
#define SS ST<<1
using namespace std; typedef long long dnt; int qu[SS], stk[SS], bg, ed, top; struct Sam {
int son[SS][], val[SS], pnt[SS], ntot;
Sam() { pnt[] = -; };
int append( int p, int c ) {
int np = ++ntot;
val[np] = val[p]+;
while( p!=- && !son[p][c] )
son[p][c]=np, p=pnt[p];
if( p==- ) {
pnt[np] = ;
} else {
int q=son[p][c];
if( val[q]==val[p]+ ) {
pnt[np] = q;
} else {
int nq = ++ntot;
memcpy( son[nq], son[q], sizeof(son[nq]) );
val[nq] = val[p]+;
pnt[nq] = pnt[q];
pnt[q] = pnt[np] = nq;
while( p!=- && son[p][c]==q )
son[p][c]=nq, p=pnt[p];
}
}
return np;
}
dnt count() {
dnt rt = ;
for( int u=; u<=ntot; u++ )
rt += val[u]-val[pnt[u]];
return rt;
}
}sam;
struct Trie {
int son[ST][], last[ST], ntot;
void insert( int *T ) {
int u=;
for( int i=; T[i]!=-; i++ ) {
int c=T[i];
if( !(<=T[i]&&T[i]<) ) {
assert( T[i]>= && T[i]<= );
}
if( !son[u][c] ) son[u][c]=++ntot;
u=son[u][c];
}
}
void build() {
last[] = ;
qu[bg=ed=] = ;
while( bg<=ed ) {
int u=qu[bg++];
for( int c=; c<; c++ ) {
int v=son[u][c];
if( !v ) continue;
last[v] = sam.append( last[u], c );
qu[++ed] = v;
}
}
}
}trie; int n, c;
int head[N], wght[N], dest[N<<], next[N<<], etot;
int dgr[N], fat[N]; void adde( int u, int v ) {
etot++;
dest[etot] = v;
next[etot] = head[u];
head[u] = etot;
}
void bfs( int s ) {
qu[bg=ed=] = s;
fat[s] = ;
while( bg<=ed ) {
int u=qu[bg++];
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] ) continue;
qu[++ed] = v;
fat[v] = u;
}
}
for( int t=; t<=top; t++ ) {
int u=stk[t];
bg=, ed=;
while( u ) {
qu[++ed] = wght[u];
u=fat[u];
}
reverse( qu+, qu++ed );
qu[++ed] = -;
trie.insert( qu+ );
}
}
int main() {
scanf( "%d%d", &n, &c );
for( int i=; i<=n; i++ )
scanf( "%d", wght+i );
for( int i=,u,v; i<n; i++ ) {
scanf( "%d%d", &u, &v );
adde( u, v );
adde( v, u );
dgr[u]++, dgr[v]++;
}
for( int u=; u<=n; u++ )
if( dgr[u]<= ) stk[++top] = u;
for( int t=; t<=top; t++ )
bfs(stk[t]);
trie.build();
printf( "%lld\n", sam.count() );
return ;
}

bzoj 3926的更多相关文章

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

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

  2. BZOJ 3926 诸神眷顾的幻想乡

    BZOJ 3926 诸神眷顾的幻想乡 开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个 既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下 ...

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

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

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

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

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

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

  6. BZOJ 3926 && ZJOI 2015 诸神眷顾的幻想乡 (广义后缀自动机)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MB Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽 ...

  7. 【BZOJ 3926】【ZJOI 2015】诸神眷顾的幻想乡

    http://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机的例题,感觉广义后缀自动机好恶心... 广义后缀自动机是对一个trie建立的后缀 ...

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

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

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

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

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

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

随机推荐

  1. Hibernate5笔记9--Hibernate注解式开发

    Hibernate注解式开发: (1)注解式开发的注意点: Hibernate中使用注解,主要是为了替代映射文件,完成“类到表,属性到字段”的映射.  JPA提供了一套功能强大的注解.Hibernat ...

  2. oracle建表,设置主键,修改属性等

    --建表 create table book( book_id number(10), book_name varchar2(20), book_price number(10,2), book_au ...

  3. 【Linux技术】ubuntu常用命令【转】

    转自:http://www.cnblogs.com/lcw/p/3159462.html 查看软件xxx安装内容:dpkg -L xxx查找软件库中的软件:apt-cache search 正则表达式 ...

  4. aarch64_l1

    L-function-1.23-18.fc26.aarch64.rpm 2017-02-14 08:01 139K fedora Mirroring Project L-function-devel- ...

  5. if(a==1) & if(1==a) 区别

    [前提] 在公司参加项目时,看到前辈写if比较数值是否相等,经常会写 if(1==a) ,觉得有些奇怪,如是乎,将调查结果写下来记录一下. [结果] if(a==1) 与 if(1==a)是没有什么区 ...

  6. Python_oldboy_自动化运维之路_全栈考试(五)

    1.执行 Python 脚本的两种方式 [root@localhost tmp]# cat a.py #!/usr/bin/python # -*- coding: UTF-8 -*- print & ...

  7. 使用qshell备份七牛云存储文件

    qshell是利用七牛文档上公开的API实现的一个方便开发者测试和使用七牛API服务的命令行工具.我们可以利用它来将七牛云上存储的文件备份到本地. 它提供Mac OSX, Linux, Windows ...

  8. 简单的TCP接受在转发到客户端的套接口

    //功能:客服端发送tcp包,服务器接受到并打印出来,并将包转换为大写后到客户端//2015.9.10成功 #include <stdio.h>#include <sys/socke ...

  9. 使用Netty4实现基本的消息分发

    示例工程代码 可从附件下载 具体的说明和用法在后面介绍 需求与目的 一个游戏服务端需要处理各种业务逻辑,每一种业务逻辑都对应着一个请求消息和一个响应消息.那么服务端需要把这些不同的消息自动分发到对应的 ...

  10. java8 - 2

    import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util. ...