【bzoj3277/bzoj3473】串/字符串 广义后缀自动机
题目描述
输入
接下来n行每行一个字符串。
输出
样例输入
3 1
abc
a
ab
样例输出
6 1 3
题解
广义后缀自动机
建立广义后缀自动机,统计一下每个节点属于多少个字符串中。
在每次插入新节点np后,parent树上np的父亲节点fa[np]一定有着np的身份,即一定包含当前串(这里将root节点视作在所有串中)。
那么沿着parent树一直向上更新即可。更新到已经被更新过的节点就停止。
这样时间复杂度是O(n)的。
求出每个节点在几个子串中以后,还要知道出现次数。
而出现次数有一个定理:x结尾的不重复字符串的出现次数=dis[x]-dis[fa[x]]。
简单证明一下:从root走到parent树上x到root的链上的点共有dis[x]种方法,走到fa[x]到root的链上的点共有dis[fa[x]]种方法,相减可推出结论。
而仅仅求出不重复字符串的出现次数还不够,我们需要统计所有的出现位置。而出现位置一定是在parent树中从x到叶子结点均出现的。
那么可以用类似于树形dp的方法求解。
总结一下:建立广义后缀自动机,同时统计每个节点在多少个字符串中出现过。保留出现在≥k个字符串中的,令出现次数为dis[x]-dis[fa[x]]。然后树形dp,c[x]+=c[fa[x]],并更新答案求解。
说了这么多,其实代码也就几十行~
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200010
using namespace std;
int a[N][26] , fa[N] , kind[N] , type[N] , si[N] , last , tot = 1;
int head[N] , to[N] , next[N] , cnt;
long long dis[N] , c[N] , ans[N];
char str[N];
void add(int x , int y)
{
to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
void ins(int t , int c)
{
int p = last , np = last = ++tot;
dis[np] = dis[p] + 1 , kind[np] = t;
while(p && !a[p][c]) a[p][c] = np , p = fa[p];
if(!p) fa[np] = 1;
else
{
int q = a[p][c];
if(dis[q] == dis[p] + 1) fa[np] = q;
else
{
int nq = ++tot;
memcpy(a[nq] , a[q] , sizeof(a[q])) , dis[nq] = dis[p] + 1 , fa[nq] = fa[q] , fa[np] = fa[q] = nq , si[nq] = si[q] , type[nq] = type[q];
while(p && a[p][c] == q) a[p][c] = nq , p = fa[p];
}
}
for(p = np ; p && type[p] != t ; p = fa[p]) si[p] ++ , type[p] = t;
}
void dfs(int x)
{
int i;
c[x] += c[fa[x]] , ans[kind[x]] += c[x];
for(i = head[x] ; i ; i = next[i])
dfs(to[i]);
}
int main()
{
int n , m , k , i , j;
scanf("%d%d" , &n , &k);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%s" , str + 1) , m = strlen(str + 1) , last = 1;
for(j = 1 ; j <= m ; j ++ ) ins(i , str[j] - 'a');
}
for(i = 2 ; i <= tot ; i ++ )
{
add(fa[i] , i);
if(si[i] >= k) c[i] = dis[i] - dis[fa[i]];
}
dfs(1);
for(i = 1 ; i <= n ; i ++ ) printf("%lld " , ans[i]);
return 0;
}
【bzoj3277/bzoj3473】串/字符串 广义后缀自动机的更多相关文章
- 【BZOJ3227】串【广义后缀自动机】
题意 给出n个字符串,问每个字符串中有多少子串是这所有的n个字符串中至少k个的子串. 分析 广义后缀自动机模板题.对这n个串建广义后缀自动机,对于每个状态维护两个值cou[u]和lcu[u]分别代表拥 ...
- BZOJ3277 串 【广义后缀自动机】
Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中 至少k个字符串的子串(注意包括本身). Input 第一行两个整数n, ...
- BZOJ 3473: 字符串 [广义后缀自动机]
3473: 字符串 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 354 Solved: 160[Submit][Status][Discuss] ...
- BZOJ 3277 串 & BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)
标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ...
- BZOJ3473 字符串 广义后缀自动机
今天主攻了下SAM 好多东西以前都没理解到 对于这道题 我们建一个自动机存所有串 每个穿last从1开始 对于自动机上每个点额外记一个cnt 表示能匹配到这个点的不同串个数 建完对每个串在自动机上匹配 ...
- BZOJ 3473 字符串 ——广义后缀自动机
这题就比较有趣了. 首先匹配一遍,然后统计子树叶子节点中包含大于等于k的节点个数(HH的项链) 然后就可以搞了. 关于合法的情况数,显然是l[i]-l[fa[i]],然后向下下传即可(YY一下). # ...
- [bzoj2780][Spoj8093]Sevenk Love Oimaster_广义后缀自动机
Sevenk Love Oimaster bzoj-2780 Spoj-8093 题目大意:给定$n$个大串和$m$次询问,每次给出一个字符串$s$询问在多少个大串中出现过. 注释:$1\le n\l ...
- JZOJ5915 [2018NOIP模拟] 明日之星(广义后缀自动机,线段树)
题目描述 给定一棵树,每个节点有一个权值 \(a_i\) 和一个字符串 \(s_i\). q组询问,每次询问一个字符串 S 和两个节点x,y: 求x到y路径上每个节点的字符串在 S 中出现的次数乘上各 ...
- CF 666E Forensic Examination——广义后缀自动机+线段树合并
题目:http://codeforces.com/contest/666/problem/E 对模式串建广义后缀自动机,询问的时候把询问子串对应到广义后缀自动机的节点上,就处理了“区间”询问. 还要处 ...
随机推荐
- 题解 P1280 【尼克的任务】
传送门 f[i]表示i~n的最长空闲时间: 如果当前无任务就休息一秒(f[i]=f[i+1]+1): 否则f[i]=max(f[i],f[i+当前工作时间]); 用结构体来记录,我们对于每一个时刻开一 ...
- Bootstrap 历练实例 - 按钮(Button)插件复选框
复选框(Checkbox) 您可以创建复选框按钮 组,并通过向 btn-group 添加 data 属性 data-toggle="buttons" 来添加复选框按钮组的切换. & ...
- 3_HA介绍和安装部署
一.hadoop 2.x产生背景 1.hadoop 1.x中hdfs和mr在高可用和扩展性等方面存在问题.2.hdfs存在的问题:NN单点故障,难以应用于在线场景:NN压力过大,内存受限,影响系统扩展 ...
- swl模拟
#import <Foundation/Foundation.h> #define NSLog(FORMAT, ...) printf("%s\n", [[NSStri ...
- XCode5 使用AutoLayout情况下改变控件的 方法
[self.viewButtonsetTranslatesAutoresizingMaskIntoConstraints:NO]; //[self.view addConstraint:[NSLayo ...
- unix环境高级编程一书中部分错误处理函数
#include <unistd.h> #include <errno.h> #include <string.h> #include <stdio.h> ...
- Android 性能篇 -- 带你领略Android内存泄漏的前世今生
基础了解 什么是内存泄漏? 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存但是由于程序逻辑错误而导致程序失 ...
- JZOJ 4732. 【NOIP2016提高A组模拟8.23】函数
4732. [NOIP2016提高A组模拟8.23]函数 (Standard IO) Time Limits: 1500 ms Memory Limits: 262144 KB Detailed ...
- 解决cmd目录下pip命令不存在的问题
解决cmd目录下pip命令不存在的问题 注:pip.exe程序在Python安装目录下的scripts中1.在cmd命令中输入: 先输入:python -m ensurepip 再输入:python ...
- unknow table alarmtemp error when drop database (mysql)
Q: unknow table alarmtemp error when drop database (mysql) D: alarmtemp is table in rtmd database. ...