BZOJ3277: 串(后缀自动机,Parent树,Dfs序)
Description
Input
Output
输出一行n个整数,第i个整数表示第i个字符串的答案。
Sample Input
abc
a
ab
Sample Output
6 1 3
解题思路:
k个嘛,好像可以离线树状数组QAQ,具体的像这样,只不过需要将所有节点都询问一遍。
最后,找子串嘛,短的不多于k个长的肯定也不行,利用这个性质,只要不够k就跳pre,直到大于等于k。
而以这个节点为后缀的子串共有len个,ans+=len就好了。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=;
struct sant{
int tranc[];
int len;
int pre;
}s[N];
struct pnt{
int hd;
int ind;
int oud;
int col;
int ans;
}p[N];
struct ent{
int twd;
int lst;
}e[N];
struct int_2{
int l;
int r;
int no;
}d[N];
int n,k;
int siz;
int dfn;
int cnt;
int fin;
char tmp[N];
int ll[N],rr[N];
int col[N];
int lst[N];
int line[N];
int str[N];
int lowbit(int x)
{
return x&(-x);
}
void update(int pos,int x)
{
while(pos&&pos<=dfn)
{
line[pos]+=x;
pos+=lowbit(pos);
}
return ;
}
int query(int pos)
{
int ans=;
while(pos)
{
ans+=line[pos];
pos-=lowbit(pos);
}
return ans;
}
bool cmp(int_2 x,int_2 y)
{
return x.r<y.r;
}
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void Insert(int c,int pl)
{
int nwp,nwq,lsp,lsq;
nwp=++siz;
s[nwp].len=s[fin].len+;
p[nwp].col=pl;
for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
s[lsp].tranc[c]=nwp;
if(!lsp)
s[nwp].pre=;
else{
lsq=s[lsp].tranc[c];
if(s[lsq].len==s[lsp].len+)
s[nwp].pre=lsq;
else{
nwq=++siz;
s[nwq]=s[lsq];
s[nwq].len=s[lsp].len+;
s[lsq].pre=s[nwp].pre=nwq;
while(s[lsp].tranc[c]==lsq)
{
s[lsp].tranc[c]=nwq;
lsp=s[lsp].pre;
}
}
}
fin=nwp;
}
void Dfs(int x)
{
p[x].ind=++dfn;
col[dfn]=p[x].col;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
Dfs(to);
}
p[x].oud=++dfn;
col[dfn]=p[x].col;
}
int main()
{
scanf("%d%d",&n,&k);
if(k>n)
{
for(int i=;i<=n;i++)
printf("%d ",);
return ;
}
fin=++siz;
for(int i=;i<=n;i++)
{
ll[i]=rr[i-]+;
rr[i]=rr[i-];
fin=;
scanf("%s",tmp);
int len=strlen(tmp);
for(int j=;j<len;j++)
str[++rr[i]]=tmp[j]-'a';
for(int j=ll[i];j<=rr[i];j++)
{
Insert(str[j],i);
}
} for(int i=;i<=siz;i++)
ade(s[i].pre,i);
Dfs();
for(int i=;i<=siz;i++)
d[i]=(int_2){p[i].ind,p[i].oud,i};
std::sort(d+,d+siz+,cmp);
int r=;
for(int i=;i<=siz;i++)
{
while(r<=d[i].r)
{
if(!col[r])
{
r++;
continue;
}
if(lst[col[r]])
update(lst[col[r]],-);
update(r,);
lst[col[r]]=r;
r++;
}
r--;
p[d[i].no].ans=query(d[i].r)-query(d[i].l-);
}
for(int i=;i<=n;i++)
{
int ans=;
int root=;
for(int j=ll[i];j<=rr[i];j++)
{
root=s[root].tranc[str[j]];
while(p[root].ans<k)
root=s[root].pre;
ans+=s[root].len;
}
printf("%d ",ans);
}
puts("");
return ;
}
BZOJ3277: 串(后缀自动机,Parent树,Dfs序)的更多相关文章
- [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增
题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...
- P2336 [SCOI2012]喵星球上的点名(后缀自动机+莫队+dfs序)
P2336 [SCOI2012]喵星球上的点名 名字怎么存?显然是后缀自动机辣 询问点到多少个喵喵喵其实就是 查询后缀自动机上parent树的一个子树 于是我们考虑莫队 怎么树上莫队呢 我们用dfs序 ...
- 洛谷2414(构建ac自动机fail树dfs序后遍历Trie树维护bit及询问答案)
要点 这是一道蔡队题,看我标题行事 任意询问y串上有多少个x串,暴力找每个节点是不是结尾肯定是炸的,考虑本质:如果某节点是x的结尾,根据ac自动机的性质,x一定是此(子)串后缀.又有每个Trie节点的 ...
- BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树
Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组
E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
- 【BZOJ-2434】阿狸的打字机 AC自动机 + Fail树 + DFS序 + 树状数组
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2022 Solved: 1158[Submit][Sta ...
- luogu5212/bzoj2555 substring(后缀自动机+动态树)
对字符串构建一个后缀自动机. 每次查询的就是在转移边上得到节点的parent树中后缀节点数量. 由于强制在线,可以用动态树维护后缀自动机parent树的子树和. 注意一个玄学的优化:每次在执行连边操作 ...
- 洛谷P4493 [HAOI2018]字串覆盖(后缀自动机+线段树+倍增)
题面 传送门 题解 字符串就硬是要和数据结构结合在一起么--\(loj\)上\(rk1\)好像码了\(10k\)的样子-- 我们设\(L=r-l+1\) 首先可以发现对于\(T\)串一定是从左到右,能 ...
- 洛谷P2178 [NOI2015]品酒大会(后缀自动机 线段树)
题意 题目链接 Sol 说一个后缀自动机+线段树的无脑做法 首先建出SAM,然后对parent树进行dp,维护最大次大值,最小次小值 显然一个串能更新答案的区间是\([len_{fa_{x}} + 1 ...
随机推荐
- 【iOS开发-34】自己主动释放池@autoreleasepool的使用注意事项以及ARC机制——面试必考内容
自己主动释放池@autorelease面试频率可能会吧release还要高. (1)在自己主动释放池@autoreleasepool{}中alloc一个对象后(如p1).仍然须要用[p1 autore ...
- 惊叹计算机运行速度的提升---以n Queens 问题为例
1 介绍 实现了书<Data Structures and Program design in C++>(Robert L. Kruse and Alexander J. Ryba, 20 ...
- 酱油记:GDKOI2018
GDKOI2018,走出机房的第六场考试 DAY0 这一次GDKOI,第一次在广州二中考,第一次住在柏高酒店(住宿条件杠杠的!),晚上就到对面的万达广场吃了顿烤肉,到老师那里开会,然后就回酒店睡了 D ...
- Exception: Operation xx of contract xx specifies multiple request body parameters to be serialized without any wrapper elements.
Operation 'CreateProductCodeStock' of contract 'IChileService' specifies multiple request body param ...
- tp5项目搭建思路
按照需求,创建主体的目录结构,一般包括管理后台admin,前台展示index,app接口api. admin中又包含controller,model,view,其他等等. 一些js,css,image ...
- 35.QQ大数据模型
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stri ...
- Python正则表达式初识(十)附正则表达式总结
今天分享正则表达式最后一个特殊字符“\d”,具体的教程如下. 1.特殊字符“\d”十分常用,其代表的意思是数字.代码演示如下图所示. 其中“+”的意思是表示连续,在这里代表的意思是连续的数字.但是输出 ...
- JS — 对象的基本操作
JS面向对象系列教程 — 对象的基本操作 面向对象概述  面向对象(Object Oriented)简称OO,它是一种编程思维,用于指导我们如何应对各种复杂的开发场景. 这里说的对象(Object) ...
- 手把手教你用vue-cli构建一个简单的路由应用
上一章说道:十分钟上手-搭建vue开发环境(新手教程)https://www.jianshu.com/p/0c6678671635 开发环境搭建好之后,那么开始新添加一些页面,构建最基本的vue项目, ...
- jQuery和JavaScript的点击事件区别
// $("#indexPage").click(); // 触发了a标签的点击事件,但是没有触发页面跳转 document.getElementById("indexP ...