BZOJ 3926 诸神眷顾的幻想乡

开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个

既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下的路径,那么以它的任意一端的子树内的某一个叶子为根必然可以变成从上到下的。否则,以它处于下端的点的子树内的叶子为根也可以做到。

所以如果以每一个叶子为根的串建成个 Trie 并且把所有单词丢进广义SAM就做完了。

说一下广义SAM的构建:

  • 最简单轻松的,如果只是插入一些字符串,那么插入一个后把 last 设置为根就好了。

    据说这种构造在某些时候是会死掉的但是好写啊,如果单词重复据说会加多点。。但是平时写由于很难出错一直写的这个。

  • 标准的,对于所有串构造一棵 Trie 然后 BFS 这个 Trie 来构造。加入一个点的时候就把 last 设置为它父亲加入完时的 last。

    注意,写 DFS 是会被卡的!可以看这篇博客

空间开小WA了发海星

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include "queue"
using namespace std;
typedef long long ll;
#define MAXN 2000006 int n , lst , m;
char ch[MAXN]; struct SAM{
int son[MAXN][11]; // sons
int par[MAXN] , len[MAXN]; // node
int cnt , ecnt;
void init( ) {
memset( son , 0 , sizeof son );
cnt = lst = 1; ecnt = 0;
}
void ins( int x ) {
int cur = ++ cnt;
len[cur] = len[lst] + 1;
int p = lst;
while( p && !son[p][x] ) son[p][x] = cur , p = par[p];
if( !p ) par[cur] = 1;
else {
int q = son[p][x];
if( len[q] == len[p] + 1 ) par[cur] = q;
else {
int cl = ++ cnt;
memcpy( son[cl] , son[q] , sizeof son[q] );
par[cl] = par[q]; // copy
len[cl] = len[p] + 1 , par[q] = par[cur] = cl;
for( ; son[p][x] == q ; p = par[p] ) son[p][x] = cl;
}
}
lst = cur;
}
int ch[MAXN][10] , pos[MAXN];
void build( ) {
init( );
queue<int> Q;
Q.push( 0 ); pos[0] = 1;
while( !Q.empty() ) {
int u = Q.front(); Q.pop();
for( int i = 0 ; i < 10 ; ++ i ) if( ch[u][i] ) {
Q.push( ch[u][i] );
lst = pos[u]; ins( i ); pos[ch[u][i]] = lst;
}
}
}
long long work( ) {
long long res = 0;
for( int i = 2 ; i <= cnt ; ++ i ) {
res += len[i] - len[par[i]];
}
return res;
}
} S ;
namespace wtf { int n , m; int head[MAXN] , to[MAXN << 1] , nex[MAXN << 1] , ecn;
void ade( int u , int v ) {
to[++ ecn] = v , nex[ecn] = head[u] , head[u] = ecn;
} int w[MAXN] , cn; void build( int u , int ps , int fa ) {
for( int i = head[u] ; i ; i = nex[i] ) {
int v = to[i];
if( v == fa ) continue;
int& x = S.ch[ps][w[v]];
if( !x ) x = ++ cn;
build( v , x , u );
}
}
int c;
void main() {
cin >> n >> c;
for( int i = 1 ; i <= n ; ++ i )
scanf("%d",&w[i]);
for( int i = 1 , u , v ; i < n ; ++ i )
scanf("%d%d",&u,&v) , ade( u , v ) , ade( v , u );
S.init();
for( int i = 1 ; i <= n ; ++ i )
if( !nex[head[i]] ) build( i , S.ch[0][w[i]] ? S.ch[0][w[i]] : ( S.ch[0][w[i]] = ++ cn ) , i );
S.build();
cout << S.work( ) << endl;
}
}
int main() {
wtf::main();
}

BZOJ 3926 诸神眷顾的幻想乡的更多相关文章

  1. [BZOJ]3926 诸神眷顾的幻想乡(ZJOI2015)

    听说大佬们都会后缀自动机. 小C看完SAM,想找个裸题练习一下模板.听说这题还是陈老师出的?(羊毛出在羊身上) Description  幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生 ...

  2. bzoj 3926: 诸神眷顾的幻想乡 广义后缀自动机

    题目: Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给 ...

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

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

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

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

  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: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]

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

  8. BZOJ 3926: [Zjoi20150]诸神眷顾的幻想乡

    3926: [Zjoi20150]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 438  Solved: 273 Descripti ...

  9. 【BZOJ3926】诸神眷顾的幻想乡(后缀自动机)

    [BZOJ3926]诸神眷顾的幻想乡(后缀自动机) 题面 BZOJ 题解 广义后缀自动机啦 求多个串的不同子串个数? 当然是后缀自动机,最后只要把\(longest-parent.longest\)求 ...

随机推荐

  1. Less-(5~7) error based

    Less-5: 核心语句: 我们注意到,当输入正确时,并不能获得有价值的回显.好在出现错误时,会爆出错误内容: 于是,使用报错注入: 1'  and updatexml(1,concat(0x7e,( ...

  2. ORA-19815: WARNING: db_recovery_file_dest_size闪回区爆满问题处理

    问题描述:有一个数据库起不来了,根据层层排查,是因为归档设置在了闪回区,文件的大小已经超出了闪回区限制.最后直接给数据库拖挂 环境:windows server2012 , oracle 19c,单机 ...

  3. Spring Cloud Gateway Route Predicate Factory 的使用

    Spring Cloud Gateway的使用 一.需求 二.基本组成 1.简介 2.核型概念 1.Route 路由 2.Predicate 谓语.断言 3.Filter 过滤器 3.工作原理 三.网 ...

  4. 基于Vue的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式

    在基于Vue的工作流项目模块中,我们在查看表单明细的时候,需要包含公用表单信息,特定表单信息两部分内容.前者表单数据可以统一呈现,而后者则是不同业务的表单数据不同.为了实现更好的维护性,把它们分开作为 ...

  5. 用Python画如此漂亮的专业插图 ?简直So easy!

    本文整理自知乎问答,仅用于学术分享,著作权归作者所有.如有侵权,请联系我删文处理.多多转发,多多学习! 方法一 强烈推荐 Python 的绘图模块 matplotlib: python plottin ...

  6. 对dy和Δy的浅薄理解

    一.导数定义 当函数y=f(x)的自变量x在一点x0上产生一个增量Δx时,函数输出值的增量Δy与自变量增量Δx的比值在Δx趋于0时的极限a如果存在,a即为在x0处的导数,记作f'(x0)或df(x0) ...

  7. jquery正则表达式验证【是否带有小数、是否中文名称组成、是否全由8位数字组成、电话码格式、邮件地址】

    1 <form name="myform" action="" onsubmit="return fun1()"> 2 < ...

  8. undefined reference to `recvIpcMsg(int, ipc_msg*)'——#ifdef __cplusplus extern "C" { #endif

    最近在弄一个进程间通信,原始测试demon用c语言写的,经过测试ok,然后把接口封装起来了一个send,一个recv. 使用的时候send端是在一个c语言写的http服务端使用,编译ok没有报错,但是 ...

  9. 平分的直线 牛客网 程序员面试金典 C++ Python

    平分的直线 牛客网 程序员面试金典 C++ Python 题目描述 在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分.假定正方形的上下两条边与x轴平行. 给定两个vecotrA和B ...

  10. cm0 逆向分析

    目录 cm0 逆向分析 前言 Strings工具复习 String工具使用说明 Strings工具解cm0题 cm0 逆向分析 前言 Emmmmm,我假装你看到这里已经学过了我的<恶意代码分析实 ...