我居然到了国赛之前才学习怎么做广义后缀自动机

这个题目……意思是……有20个叶子,肯定一条路径都是任意一个叶子为根,一个从某个点往祖先走的路径

这样的话我们可以按照dfs序,从每个节点的父亲那里的后缀自动机节点再加一个节点

这样只要对于每个后缀自动机的节点统计一下节点长度减去父亲节点长度就好了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <random>
#include <ctime>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
struct node {
int to,next;
}E[MAXN * 2];
int N,C,col[MAXN],sumE,head[MAXN],deg[MAXN];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
struct sam {
struct node {
int len,par,nxt[10];
}tr[MAXN * 40];
int tail,root,last;
void Init() {
root = last = ++tail;
}
int expend(int x,int c) {
if(tr[x].nxt[c] && tr[tr[x].nxt[c]].len == tr[x].len + 1) return tr[x].nxt[c];
int nw = ++tail,p;
tr[nw].len = tr[x].len + 1;
for(p = x ; p && !tr[p].nxt[c] ; p = tr[p].par) {
tr[p].nxt[c] = nw;
}
if(!p) tr[nw].par = root;
else {
int q = tr[p].nxt[c];
if(tr[q].len == tr[p].len + 1) tr[nw].par = q;
else {
int cq = ++tail;
tr[cq] = tr[q];
tr[cq].len = tr[p].len + 1;
tr[q].par = tr[nw].par = cq;
for(; p && tr[p].nxt[c] == q ; p = tr[p].par) {
tr[p].nxt[c] = cq;
}
}
}
return nw;
}
int64 Calc() {
int64 res = 0;
for(int i = 1 ; i <= tail ; ++i) {
res += tr[i].len - tr[tr[i].par].len;
}
return res;
}
}SAM;
void dfs(int u,int fa,int p) {
p = SAM.expend(p,col[u]);
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs(v,u,p);
}
}
}
void Solve() {
read(N);read(C);
for(int i = 1 ; i <= N ; ++i) read(col[i]);
int u,v;
for(int i = 1 ; i < N ; ++i) {
read(u);read(v);
add(u,v);add(v,u);
++deg[v];++deg[u];
}
SAM.Init();
for(int i = 1 ; i <= N ; ++i) {
if(deg[i] == 1) dfs(i,0,SAM.root);
}
out(SAM.Calc());enter;
}
int main() {
#ifdef ivorysi
freopen("f3.in","r",stdin);
#endif
Solve();
}

【LOJ】#2137. 「ZJOI2015」诸神眷顾的幻想乡的更多相关文章

  1. 【ZJOI2015】诸神眷顾的幻想乡 解题报告

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

  2. 【bzoj3926】【Zjoi2015】诸神眷顾的幻想乡

    题解: 如果树上某个路径串的端点不是叶子,那么一定是另一个串的子串: 这样只对叶子$dfs$把$20*20$个串插入广义$SAM$就是统计本质不同的串的个数的模板了: 我不太会分析广义$SAM$的空间 ...

  3. 【BZOJ3926】【ZJOI2015】诸神眷顾的幻想乡 广义后缀自动机

    题目: 题目在这里 思路&做法: 参考的题解 既然只有\(20\)个叶子节点, 那么可以从每个叶子节点往上建一颗\(trie\)树, 然后合并成一棵大的\(trie\)树, 然后构建广义后缀自 ...

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

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

  5. bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对[广义后缀自动机]的一些理解

    先说一下对后缀自动机的理解,主要是对构造过程的理解. 构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢? 首先,子串$[0,L+1)$对应的状态不存 ...

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

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

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

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

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

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

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

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

随机推荐

  1. scala 递归读取文件夹下所有的指定后缀的文件

    def getFile(file:File): Array[File] ={ val files = file.listFiles().filter(! _.isDirectory) .filter( ...

  2. Vue进阶(Bus/作用域slot/动态组件)

    一.Vue非父子组件传值(Bus/总线/发布订阅模式/观察者模式) 我们在之前已经知道了父子传值.父组件传递过来了的值,在子组件通过props接受,然后就可以使用了. 也学过了隔代传值,均是通过pro ...

  3. Choosing a fast unique identifier (UUID) for Lucene——有时间再看下

    Most search applications using Apache Lucene assign a unique id, or primary key, to each indexed doc ...

  4. Integer面试连环炮以及源码分析(转)

    场景:   昨天有位朋友去面试,我问他面试问了哪些问题,其中问了Integer相关的问题,以下就是面试官问的问题,还有一些是我对此做了扩展. 问:两个new Integer 128相等吗? 答:不.因 ...

  5. python开发-实现redis中的发布订阅功能

    Python3学习(二十七):python实现Redis的订阅与发布(sub-pub机制) 先介绍一下redis的pub/sub功能: Pub/Sub功能(means Publish, Subscri ...

  6. 使用Docker快速搭建Tensorflow开发环境

    当我刚开始学习使用scikit-learn时,总是会出现各种各样的包依赖问题,兜兜转转了一遍才全部安装好,现在的机器学习算法开发者大都使用tensorflow.pytorch来实现自己的想法,但依然会 ...

  7. 002-创建型-05-原型模式(Protype)

    一.概述 指原型实例指定创建对象的种类,并通过克隆这些原型创建新的对象 原型模式就是让类实现Cloneable接口,达到克隆原型类的方式. 1.1.适用场景 1.在创建对象的时候,我们不只是希望被创建 ...

  8. Git——起步(待续)

    原文链接:Getting Started with Git

  9. MHA集群搭建

    (1).简介 MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开 ...

  10. SM30维护视图屏蔽按钮

    标准维护视图  GUI状态  ESLG 编辑按钮 AEND 达到效果 DATA: l_act TYPE char1, l_name TYPE dd02v-tabname. DATA: lt_vimex ...