今天主攻了下SAM 好多东西以前都没理解到
对于这道题 我们建一个自动机存所有串 每个穿last从1开始
对于自动机上每个点额外记一个cnt 表示能匹配到这个点的不同串个数
建完对每个串在自动机上匹配 把到的每个点$x$和$par[x],par[par[x]]…$的$cnt++$  
然后就从父亲往儿子传递一下 这样每个点i就存了所有≤≤len[i]的数量 这里我用的拓扑序转移
最后再对每个串在自动机上跑一遍 统计答案就好啦~

  1. #include<bits/stdc++.h>
  2. #define bug(x) cout<<(#x)<<" "<<(x)<<endl
  3. #define ll long long
  4. /*
  5. char *TT,*mo,but[(1<<15)+2];
  6. #define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
  7. using namespace std;
  8. const int N=2e5+5;
  9. inline int read(){
  10. int x=0,f=1;char ch=getchar();
  11. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  12. while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
  13. return x*f;
  14. }
  15. ll ans[N];
  16. int n,k,amaz,tot,rt,last,cnt[N],ch[N][27],len[N],par[N],l[N],tmp[N],sum[N],dig[N],vis[N];
  17. string a[N];
  18. void extend(int x){
  19. int p=last,np=++tot;
  20. last=np,len[np]=len[p]+1;
  21. for(;p&&!ch[p][x];p=par[p]) ch[p][x]=np;
  22. if(!p) par[np]=rt;
  23. else{
  24. int q=ch[p][x];
  25. if(len[q]==len[p]+1) par[np]=q;
  26. else{
  27. int nq=++tot;
  28. memcpy(ch[nq],ch[q],sizeof ch[q]);
  29. len[nq]=len[p]+1;
  30. par[nq]=par[q];par[q]=par[np]=nq;
  31. for(;p&&ch[p][x]==q;p=par[p]) ch[p][x]=nq;
  32. }
  33. }
  34. }
  35. void top(){
  36. queue<int>q;
  37. for(int i=1;i<=tot;i++) if(!dig[i]) q.push(i),tmp[++amaz]=i;
  38. while(!q.empty()){
  39. int x=q.front();q.pop();
  40. if(!--dig[par[x]]) {
  41. q.push(par[x]),tmp[++amaz]=par[x];
  42. }
  43. }
  44. for(int i=amaz;i;i--) sum[tmp[i]]+=sum[par[tmp[i]]];
  45. }
  46. int main(){
  47. #ifdef Devil_Gary
  48. freopen("in.txt","r",stdin);
  49. #endif
  50. n=read(),k=read();
  51. rt=tot=last=1;
  52. for(int i=1;i<=n;i++){
  53. cin>>a[i];
  54. l[i]=a[i].length();
  55. last=1;
  56. for(int j=0;j<l[i];j++) extend(a[i][j]-'a');
  57. }
  58. for(int j=1;j<=n;j++){
  59. int p=1;
  60. for(int i=0;i<l[j];i++){
  61. p=ch[p][a[j][i]-'a'];
  62. int x=p;
  63. while(x&&vis[x]!=j) {
  64. cnt[x]++,vis[x]=j,x=par[x];
  65. }
  66. }
  67. }
  68. for(int i=1;i<=tot;i++) dig[par[i]]++,sum[i]=(cnt[i]>=k)?(len[i]-len[par[i]]):0;
  69. top();
  70. for(int j=1;j<=n;j++){
  71. int p=1;
  72. for(int i=0;i<l[j];i++){
  73. p=ch[p][a[j][i]-'a'];
  74. ans[j]+=sum[p];
  75. }
  76. printf("%lld ",ans[j]);
  77. }
  78. return 0;
  79. }

BZOJ3473 字符串 广义后缀自动机的更多相关文章

  1. 【bzoj3277/bzoj3473】串/字符串 广义后缀自动机

    题目描述 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). 输入 第一行两个整数n,k.接下来n行每行一个 ...

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

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

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

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

  4. 2018.12.22 bzoj3473: 字符串(后缀自动机+启发式合并)

    传送门 调代码调的我怀疑人生. 启发式合并用迭代写怎么都跑不过(雾 换成了dfsdfsdfs版本的终于过了233. 题意简述:求给出nnn个字串,对于每个给定的字串求出其有多少个字串在至少kkk个剩下 ...

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

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

  6. BZOJ3473 字符串 【广义后缀自动机】

    题目 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? 输入格式 第一行两个整数n,k. 接下来n行每行一个字符串. 输出格式 一行n个整数,第i个整数表 ...

  7. 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 ...

  8. BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串

    https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比 ...

  9. [bzoj3277==bzoj3473]出现k次子串计数——广义后缀自动机+STL

    Brief Description 给定n个字符串,对于每个字符串,您需要求出在所有字符串中出现次数大于等于k次的子串个数. Algorithm Design 先建立一个广义后缀自动机,什么是广义后缀 ...

随机推荐

  1. re-sign重签名

    准备: ① re-sign.jar重签名工具:(下载地址为:http://troido.de/downloads/category/1): ② 从D:\Android\sdk\build-tools\ ...

  2. shell 数组基础->

    数组其实也算是变量, 传统的变量只能存储一个值, 但数组可以存储多个值. 普通数组:只能使用整数 作为数组索引 [有序 0 1 2 3 4 ]关联数组:可以使用字符串 作为数组索引 [无序 name ...

  3. RabbitMQ--Publish/Subscribe(三)

    前言 在先前例子中我们创建了一个work queue,封装一个task到一个message中并发送到queue.一个worker(consumer)取出任务并执行. 像这种producer把messa ...

  4. dc

    http://www.cnblogs.com/yjmyzz/p/docker-install-tutorial.html https://segmentfault.com/a/119000000510 ...

  5. python随笔(二)

    range(2,10):不包括10 range(2,10,3):步长为3 range(10,2,-1):从10到2,步长-1.

  6. 洛谷P1177快速排序

    传送门 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...

  7. performance 判断页面是以哪种方式进入的

    if (window.performance) { console.info("window.performance is supported"); console.log(per ...

  8. Jenkins 集成 Sonar

    Jenkins 与 Sonar 集成:Sonar 是 Jenkins 之外独立运行的一个服务.Jenkins 中安装插件 SonarQube(并配置其 Sonar Server 的 URL / Acc ...

  9. 【LOJ】#2069. 「SDOI2016」齿轮

    题解 我一开始还努力想这道题是不是有坑,被SDOI折磨到我觉得不能有那么水的题在-- 就是带权并查集维护一下两点间距离,如果新加一条边两个点在同一集合,看看已有的路径和新加的路径是否相等 乘积可以在模 ...

  10. 自动化CI构建工具

    hudson/maven jenkins,bamboo, hudson