BZOJ3926 ZJOI2015 诸神眷顾的幻想乡 Trie、广义SAM
树上的任意一条路径一定会在以某一个叶子节点为根的树上成为一条直上直下的链,而总共只有\(20\)个叶子节点。
于是每一次选所有叶子节点中的一个作为根,形成一个\(Trie\),把\(20\)个\(Trie\)统一到一个\(Trie\)上,然后对这个总的\(Trie\)建立广义后缀自动机,最后统计一下广义SAM每个节点代表的字符串个数求和。
在\(Trie\)上BFS建立广义SAM可以做到\(O(20NA)\)的复杂度,把\(20\)个\(Trie\)直接一个个插入SAM在线建会多一个\(O(\text{总Trie上所有叶子节点的深度和})\),证明见2015lyy的论文。
#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<queue>
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
}
const int MAXN = 4e6 + 7 , MAXM = 1e5 + 7;
namespace SAM{
int trans[MAXN][10] , fa[MAXN] , Lst[MAXN] , Sst[MAXN];
int N , cnt = 1;
int insert(int p , int l , int x){
int t = ++cnt;
Lst[t] = l;
while(p && !trans[p][x]){
trans[p][x] = t;
p = fa[p];
}
if(!p){
fa[t] = Sst[t] = 1;
return t;
}
int q = trans[p][x];
Sst[t] = Lst[p] + 2;
if(Lst[q] == Lst[p] + 1){
fa[t] = q;
return t;
}
int k = ++cnt;
memcpy(trans[k] , trans[q] , sizeof(trans[q]));
Lst[k] = Lst[p] + 1; Sst[k] = Sst[q];
Sst[q] = Lst[p] + 2;
fa[k] = fa[q]; fa[q] = fa[t] = k;
while(trans[p][x] == q){
trans[p][x] = k;
p = fa[p];
}
return t;
}
long long calc(){
long long ans = 0;
for(int i = 2 ; i <= cnt ; ++i)
ans += Lst[i] - Sst[i] + 1;
return ans;
}
}
struct Edge{
int end , upEd;
}Ed[MAXM << 1];
int col[MAXM] , head[MAXM] , in[MAXM] , ch[MAXN][10] , ind[MAXN] , dep[MAXN];
int N , C , cnt = 1 , cntEd;
inline void addEd(int a , int b){
Ed[++cntEd] = Edge{b , head[a]};
head[a] = cntEd;
++in[b];
}
void dfs(int x , int p , int cur){
if(!ch[cur][col[x]])
ch[cur][col[x]] = ++cnt;
cur = ch[cur][col[x]];
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(Ed[i].end != p)
dfs(Ed[i].end , x , cur);
}
void create(){
ind[1] = 1;
queue < int > q;
q.push(1);
while(!q.empty()){
int t = q.front();
q.pop();
for(int i = 0 ; i < 10 ; ++i)
if(ch[t][i]){
dep[ch[t][i]] = dep[t] + 1;
ind[ch[t][i]] = SAM::insert(ind[t] , dep[ch[t][i]] , i);
q.push(ch[t][i]);
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
N = read();
C = read();
for(int i = 1 ; i <= N ; ++i)
col[i] = read();
for(int i = 1 ; i < N ; ++i){
int a = read() , b = read();
addEd(a , b); addEd(b , a);
}
for(int i = 1 ; i <= N ; ++i)
if(in[i] == 1)
dfs(i , 0 , 1);
create();
cout << SAM::calc();
return 0;
}
BZOJ3926 ZJOI2015 诸神眷顾的幻想乡 Trie、广义SAM的更多相关文章
- bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对[广义后缀自动机]的一些理解
先说一下对后缀自动机的理解,主要是对构造过程的理解. 构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢? 首先,子串$[0,L+1)$对应的状态不存 ...
- 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 974 Solved: 573 Descriptio ...
- BZOJ3926 ZJOI2015诸神眷顾的幻想乡(广义后缀自动机)
对多串建立SAM的一种方法是建trie再对trie建SAM.构造方式分为在线(也即不建trie而是依次插入每个串,或在trie上dfs)和离线(也即建好trie再bfs).其中离线构造与单串的构造方式 ...
- BZOJ3926 Zjoi2015 诸神眷顾的幻想乡【广义后缀自动机】
Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看. ...
- BZOJ3926 [Zjoi2015]诸神眷顾的幻想乡 【广义后缀自动机】
题目 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常高兴 ...
- BZOJ3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)
Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看. ...
- 2018.12.22 bzoj3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)
传送门 题意简述:给出一棵trietrietrie树,每个点表示一个字符,求树上所有路径组成的不同字串数.(叶子数≤20\le 20≤20) 由于有一个神奇的条件,考虑以每一个叶子为树根统计每个点到树 ...
- bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机)
bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机) bzoj Luogu 题解时间 给你个无根trie树(你管这叫trie树?),问你选取一条 ...
- BZOJ3926 [Zjoi2015]诸神眷顾的幻想乡 字符串 SAM
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3926.html 题目传送门 - BZOJ3926 题意 给定一个有 $n$ 个节点,最多只有 $20$ ...
随机推荐
- java 约束配置文件和本地约束
一.寻找spring配置文件约束头(也可直接复制已有的) 1.在本地文件夹解压spring核心包(dist) 例:核心包的约束位置(D:\JavaSources\spring-framework-4. ...
- CSS字体超出两行省略
text-overflow: -o-ellipsis-lastline;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-w ...
- SEO高级技巧
原文地址:http://www.it28.cn/sousuoyinqing/853115.html 现在提起SEO来最少能让一部人感到痛苦,为什么呢,因为他们看不到希望,他们追求的永远是排名,其实SE ...
- Android学习笔记----ArcGIS在线地图服务(Android API)坐标纠偏
仅限于如下ArcGIS在线地图服务(高德提供数据): //概述:彩色中文含兴趣点版中国基础地图 //投影:WGS 1984 Web-Mercator //切片格式:MIXED90 //服务类型:基础地 ...
- Web API 方法的返回类型、格式器、过滤器
一.Action方法的返回类型 a) 操作方法的返回类型有四种:void.简单或复杂类型.HttpResponseMessage类型.IHttpActionResult类型. b) 如果返回类型为vo ...
- OkHttp3源码详解(二) 整体流程
1.简单使用 同步: @Override public Response execute() throws IOException { synchronized (this) { if (execut ...
- 对word2vec的理解及资料整理
对word2vec的理解及资料整理 无他,在网上看到好多对word2vec的介绍,当然也有写的比较认真的,但是自己学习过程中还是看了好多才明白,这里按照自己整理梳理一下资料,形成提纲以便学习. 介绍较 ...
- 洗礼灵魂,修炼python(46)--巩固篇—如虎添翼的property
@property 在前面装饰器一章中,提过一句话,装饰器也可以用于类中,确实可以的,并且python的类也内置了一部分装饰器.并且在前两章的hasattr等四个内置方法中,也说过其用法很类似装饰器, ...
- go xorm增删改查
1.增加 如果传入的bean不是完整的bean,并且传入了地址,则调用结束后会被赋值// InsertOne insert only one struct into database as a rec ...
- python遍历本地文件系统 按文件大小排序
在这个例子中,主要会用到python内置的和OS模块的几个函数: os.walk() : 该方法用来遍历指定的文件目录,返回一个三元tuple(dirpath, dirnames, filenames ...