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. TypeError: module() takes at most 2 arguments (3 given)

    1. 错误提示 2. 代码 class Parent: """定义父类""" def __init__(self): print(" ...

  2. k8s replicaset controller分析(2)-核心处理逻辑分析

    replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...

  3. Java:创建对象小记

    Java:创建对象小记 对 Java 中的创建对象的内容,做一个微不足道的小小小小记 创建对象的方式概述 使用 new 关键字:Person person = new Person(); 反射创建:使 ...

  4. spring security中ajax超时处理

    spring security为我们的系统提供了方便的认证和授权操作.在系统中完成认证和授权后,一般页面页面上大多数是ajax和后台进行操作,那么这个时候可能就会面临session超时,ajax去访问 ...

  5. Asp.Net mvc4 +Spring

    添加相应的引用对象.(以下全部) 修改mvc的Global.asax文件内容 需要将控制器中原来需要new出来的对象改成属性成员 添加这个属性的注入对象 再去修改spring对web.config的一 ...

  6. 二叉树中和为某一值的路径 牛客网 程序员面试金典 C++ Python

    二叉树中和为某一值的路径 牛客网 程序员面试金典 题目描述 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一 ...

  7. x64 InlineHook 黑魔法

    目录 x64 InlineHook 黑魔法 为什么不能用X86 的HOOK方式? 原理:jmp + rip 进行寻址6字节方式跳转 手动InlineHook 临时地址x(找一块空内存) 计算偏移 源地 ...

  8. openssh 7.4 升级 8.3

    1.删除旧版本(如果是远程连接升级,不能卸载旧版本,否则连接会断开.安装8.3完也不能卸载7.4,否则要到服务器直连重新安装8.3.) # rpm -qa |grep openssh #rpm -e ...

  9. etcd原理详解代码剖析

    1 架构 从etcd的架构图中我们可以看到,etcd主要分为四个部分. HTTP Server: 用于处理用户发送的API请求以及其它etcd节点的同步与心跳信息请求. Store:用于处理etcd支 ...

  10. Linux wget 命令 使用总结

    简介 wget命令用来从指定的URL下载文件.wget非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕.如果是服务器 ...