bzoj 3926
后缀自动机扩展到树形结构上。
先建出大的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的更多相关文章
- 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 974 Solved: 573 Descriptio ...
- BZOJ 3926 诸神眷顾的幻想乡
BZOJ 3926 诸神眷顾的幻想乡 开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个 既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1017 Solved: 599[Submit][S ...
- bzoj 3926 [Zjoi2015]诸神眷顾的幻想乡(SAM)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3926 [题意] 给定一棵树,每个节点都有相应的颜色,且保证叶子数不超过20,问 ...
- 字符串(广义后缀自动机):BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 843 Solved: 510[Submit][St ...
- BZOJ 3926 && ZJOI 2015 诸神眷顾的幻想乡 (广义后缀自动机)
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MB Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽 ...
- 【BZOJ 3926】【ZJOI 2015】诸神眷顾的幻想乡
http://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机的例题,感觉广义后缀自动机好恶心... 广义后缀自动机是对一个trie建立的后缀 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1124 Solved: 660[Submit][S ...
- ●BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3926题解&&代码: 后缀自动机,Trie树 如果以每个叶子为根,所有的子串一 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串
https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比 ...
随机推荐
- Floyd_Warshall算法
Floyd_Warshall算法主要用于求解所有节点对的最短路径,代码如下: #include<iostream> using namespace std; #define Inf 655 ...
- 音频自动增益 与 静音检测 算法 附完整C代码【转】
转自:https://www.cnblogs.com/cpuimage/p/8908551.html 前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用 ...
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()【转】
转自:http://blog.csdn.net/droidphone/article/details/8104433 我们已经在前面几章介绍了低分辨率定时器和高精度定时器的实现原理,内核为了方便其它子 ...
- TableView 的那些坑
1. 分割线填满cell宽度, 并且设置分割线的颜色 1.1 利用系统的分割线填充 1.1.1 tableView 设置如下属性 // 给tableView设置如下属性值 tableView.layo ...
- ntp/系统时钟/硬件时钟/双系统下计算机时间读取的问题
http://blog.chinaunix.net/uid-182041-id-3464524.html //linux系统时间和硬件时钟问题(date和hwclock) http://j ...
- docker stack 部署容器监控方案(cAdvisor、Prometheus、Grafana)
=============================================== 2018/7/8_第1次修改 ccb_warlock === ...
- 根据经纬度坐标计算距离-python
一.两个坐标之间距离计算 参考链接: python实现 1.Python 根据地址获取经纬度及求距离 2.python利用地图两个点的经纬度计算两点间距离 LBS 球面距离公式 美团app筛选“离我最 ...
- Fiddler 4 抓包(APP HTTPS )
一.手机连接Fiddler 1.配置fiddler 1.安装fiddler,基本下一步下一步即可: 2.打开fiddler,点击顶部栏Tools——>Options 3.在HTTPS页签勾选“D ...
- Unix IPC之基于共享内存的计数器
目的 本文主要实现一个基于共享内存的计数器,通过父子进程对其访问. 本文程序需基于<<Unix网络编程-卷2>>的环境才能运行.程序中大写开头的函数为其小写同名函数的包裹函数, ...
- 生成Insert语句的存储过程
) drop procedure [dbo].[spGenInsertSQL] GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO )) as b ...