【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 对模式串建广义后缀自动机,询问的时候把询问子串对应到广义后缀自动机的节点上,就处理了“区间”询问. 还要处 ...
随机推荐
- python基础一 day16 匿名函数
def add(x,y): return x+y add = lambda x,y:x+yprint(add(1,2)) dic={'k1':10,'k2':100,'k3':30}def func( ...
- Drupal7新装一个主题时页面白屏,如何设置一个默认主题?
问题: 请问我不小心退出登陆了 但这个主题没有登录口 而且之前不知道为什么我其他界面都不能显示内容所以 ?q=user 也不行,怎么办呢?看网上说更换默认主题 去variable表里把默认主题换了,我 ...
- vue项目跨域问题
跨域 了解同源政策:所谓"同源"指的是"三个相同". 协议相同 域名相同 端口相同 解决跨域 jsonp 缺点:只能get请求 ,需要修改B网站的代码 cors ...
- 32-1题:不分行从上到下打印二叉树/BFS/deque/queue
题目 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 考点 1.广度优先遍历 2.binary tree 3.queue 4.deque 思路 按层打印:8.6.10.5.7.9.11 用ST ...
- BZOJ2287: 【POJ Challenge】消失之物(背包dp)
题意 ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” ...
- Python基础-Python注释
一.什么是注释.特性 1.一段文字性的描述,通过注释,可以解释和明确Python代码的功能,并记录将来要修改的地方. 2.当程序处理时,Python解释器会自动忽略,不会被当做代码进行处理 二.注释的 ...
- redis 设置密码验证
1.找到配置文件:如/etc/redis/redis.conf 2.找到以下内容 # requirepass foobared 3.修改为(redispassword是密码) requirepass ...
- django 图片上传与显示
由于图片上传的需要,学习了一波上传 1. 上传 前端代码 <form action="写上相应的定向位置" method="post" enctype=& ...
- 破解studio 3T
方法一: 打开注册表:regedit 计算机\HKEY_CURRENT_USER\Software\JavaSoft\Prefs\3t\mongochef\enterprise 将里面得数据清零,又是 ...
- PHP判断时关于null,0,true,flase的值
<?php// $wh = 0; //等于整数0,等于字符串'0',等于空字符串,等于空格字符串, 等于空(null),等于字符串('null')// $wh = '0'; //=>等于整 ...