思路

广义SAM的题目,先全部插入,然后每个字符串在SAM上匹配,如果发现当前sz小于k(就是前缀不满足条件),就跳fail(找前缀的后缀,就是找子串)到满足条件为止,然后一个满足条件的节点,它的所有parent Tree上的祖先也必定满足条件,所以一个满足条件的节点的贡献就是它的maxlen

ps:貌似求sz除了我这种,还可以set启发式合并

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#include <queue>
using namespace std;
int maxlen[201000],minlen[201000],trans[201000][26],suflink[201000],ans[201000],sz[201000],last[201000],endpos[201000],Nodecnt,n;
string s[101000];
int New_state(int _maxlen,int _minlen,int *_trans,int _sz,int _last,int _suflink){
++Nodecnt;
maxlen[Nodecnt]=_maxlen;
minlen[Nodecnt]=_minlen;
if(_trans)
for(int i=0;i<26;i++)
trans[Nodecnt][i]=_trans[i];
sz[Nodecnt]=_sz;
last[Nodecnt]=_last;
suflink[Nodecnt]=_suflink;
return Nodecnt;
}
void update(int u,int x){
while(u&&last[u]!=x){
last[u]=x;
sz[u]++;
u=suflink[u];
}
}
int add_len(int u,int c,int inq){
if(trans[u][c]){
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
update(v,inq);
endpos[v]++;
return v;
}
int y=New_state(maxlen[u]+1,0,trans[v],sz[v],last[v],suflink[v]);
suflink[v]=y;
minlen[v]=maxlen[y]+1;
while(u&&trans[u][c]==v){
trans[u][c]=y;
u=suflink[u];
}
minlen[y]=maxlen[suflink[y]]+1;
update(y,inq);
return y;
}
else{
int z=New_state(maxlen[u]+1,0,NULL,0,0,0);
endpos[z]=1;
while(u&&trans[u][c]==0){
trans[u][c]=z;
u=suflink[u];
}
if(!u){
suflink[z]=1;
minlen[z]=1;
update(z,inq);
return z;
}
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
suflink[z]=v;
minlen[z]=maxlen[v]+1;
update(z,inq);
return z;
}
int y=New_state(maxlen[u]+1,0,trans[v],sz[v],last[v],suflink[v]);
suflink[v]=suflink[z]=y;
minlen[v]=minlen[z]=maxlen[y]+1;
while(u&&(trans[u][c]==v)){
trans[u][c]=y;
u=suflink[u];
}
minlen[y]=maxlen[suflink[y]]+1;
update(z,inq);
return z;
}
}
int k,in[200100];
queue<int> q;
int main(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
Nodecnt=1;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
// scanf("%s",s+1);
cin>>s[i];
int last=1,len=s[i].length();
// cout<<len<<endl;
for(int j=0;j<len;j++)
last=add_len(last,s[i][j]-'a',i);
}
for(int i=1;i<=n;i++){
int lent=s[i].length(),p=1;
// cout<<"!"<<lent<<endl;
int ans=0;
for(int j=0;j<lent;j++){
p=trans[p][s[i][j]-'a'];
while(sz[p]<k)
p=suflink[p];
if(p==0){
p=1;
continue;
}
ans+=(maxlen[p]);
}
printf("%d ",ans);
}
return 0;
}

BZOJ 3473 字符串的更多相关文章

  1. BZOJ 3277 串 & BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)

    标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ...

  2. BZOJ 3473: 字符串 [广义后缀自动机]

    3473: 字符串 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 354  Solved: 160[Submit][Status][Discuss] ...

  3. bzoj 3473 字符串 - 后缀数组 - 树状数组

    题目传送门 传送门 题目大意 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串 先用奇怪的字符把所有字符串连接起来. 建后缀树,数每个节点的子树内包含多少属 ...

  4. bzoj 3277 串 && bzoj 3473 字符串 && bzoj 2780 [Spoj]8093 Sevenk Love Oimaster——广义后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3277 https://www.lydsy.com/JudgeOnline/problem.p ...

  5. BZOJ 3277: 串/ BZOJ 3473: 字符串 ( 后缀数组 + RMQ + 二分 )

    CF原题(http://codeforces.com/blog/entry/4849, 204E), CF的解法是O(Nlog^2N)的..记某个字符串以第i位开头的字符串对答案的贡献f(i), 那么 ...

  6. BZOJ 3473: 字符串 (广义后缀自动机)

    /* 广义后缀自动机, 每次加入维护 该right集合的set, 然后可以更新所有的parent,最终能够出现在k个串中right集合也就是set大小大于等于k的部分 这样的话就给了我们要跳的节点加了 ...

  7. BZOJ 3473 字符串 ——广义后缀自动机

    这题就比较有趣了. 首先匹配一遍,然后统计子树叶子节点中包含大于等于k的节点个数(HH的项链) 然后就可以搞了. 关于合法的情况数,显然是l[i]-l[fa[i]],然后向下下传即可(YY一下). # ...

  8. bzoj 3277: 串 & bzoj 3473: 字符串【后缀自动机||后缀数组】

    建一个广义后缀自动机(每加完一个串都返回root),在parent树上dpsum记录合法长度,打着时间戳往上跳,最后每个串在自动机上跑一变统计答案即可. 后缀数组理解起来可能方便一点,但是难写,就只说 ...

  9. 【BZOJ 3473】 字符串 (后缀数组+RMQ+二分 | 广义SAM)

    3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串 ...

随机推荐

  1. Mybatis+Mysql逆向工程

    目录结构: pom文件: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...

  2. Java学习-051-Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError

    错误信息:Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting St ...

  3. Linux - ansible 安装

    # 安装依赖 yum install rpm-build python2-devel sshpass PyYAML python-jinja2 python-paramiko python-six p ...

  4. JVM深入:JVM内存堆布局图解分析(转)

    转载自:https://www.cnblogs.com/SaraMoring/p/5713732.html 原文:http://www.codeceo.com/article/jvm-memory-s ...

  5. 游戏全区全服和分区分服 QQ斗地主的设计

    游戏全区全服和分区分服  QQ斗地主的设计 https://cloud.tencent.com/community/article/164816001481011910?fromSource=gwzc ...

  6. 2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用

    2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用 一. 实践内容(3.5分) 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要 ...

  7. pytorch打印模型结构图

    import torchsummary from torchvision.models.resnet import * net = resnet18().cuda() print(net) 打印出来的 ...

  8. 图表管理账单的NABCD

    首先,我们团队的项目目标是记账本.就我个人理解,记账本中心功能有两项,第一,记录:第二,显示.而本篇博客主要描述用各种不同的图表来显示的NABCD. 首先是N(need),用户的需求就是我们的动力!利 ...

  9. JSON错误

    今天遇到了json转换的错误. 原因:少导入了jar包 解决方法把所有的jar导入

  10. 怎样的操作才能让HashMap以红黑树类型存储数据? (文中没有解答该问题)

    怎样才能让HashMap以红黑树类型存储数据? 看上面的代码可知:如果一个Node的长度大于等于7.就会触发Node转TreeNode的操作. 我向一个map中插入了一百万条数据(插入一亿条时,内存溢 ...