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 ...
随机推荐
- 深入理解maven及应用(一):生命周期和插件
在项目里用了快一年的maven了,近期突然发现maven项目在eclipse中build时很慢,由于经经常使用clean install命令来build项目,也没有管那么多,但近期实在受不了乌龟一样的 ...
- 【android】getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()的作用
getCacheDir()方法用于获取/data/data/<application package>/cache目录 getFilesDir()方法用于获取/data/data/< ...
- Lesson 2 Building your first web page: Part 3
Time to build your first HTML page by hand I could go on with more theory and send half of you to sl ...
- Hive的单节点集群详细启动步骤
说在前面的话, 在这里,推荐大家,一定要先去看这篇博客,如下 再谈hive-1.0.0与hive-1.2.1到JDBC编程忽略细节问题 Hadoop Hive概念学习系列之hive三种方式区别和搭建. ...
- AtCoder Beginner Contest 067 D - Fennec VS. Snuke
D - Fennec VS. Snuke Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statement F ...
- BZOJ3105: [cqoi2013]新Nim游戏(Xor线性无关组)
Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴 ...
- Yeslab 华为安全HCIE-第七门-Agile Controlle
课程目录: 华为安全HCIE-第七门-Agile Controller(12篇)\1_aglie_controller产品亮点讲解.avi 华为安全HCIE-第七门-Agile Controlle ...
- 快速安装Nginx及配置详解(未完待续)
导读: Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器,从2007年被德国人开发出来后可以说在市场的占有率一路飙升,因为它支持高并 ...
- [Android]新建项目继承Activity不继承ActionBarActivity
在SDK更新后,在eclipse新建Android项目时.我们常常会碰到这样一种事情:新建的MainActivity不再继承Activity而是继承ActionBarActivity,因为一些人的开发 ...
- RISC-V指令集的诞生,"V"也表示变化(variation)和向量(vectors)
RISC-V登场,Intel和ARM会怕吗? 张竞扬 摩尔精英 摩尔精英.创始人兼CEO 82 人赞了该文章 在2015年12月的Nature网站上,由U.C. Berkeley等几个大学的研究人员主 ...