3473: 字符串

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 354  Solved: 160
[Submit][Status][Discuss]

Description

给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串?

Input

第一行两个整数n,k。
接下来n行每行一个字符串。

Output

一行n个整数,第i个整数表示第i个字符串的答案。
字符串总长度L
n,k,L<=1e5

研究了两节多课广义后缀自动机是什么,还看了2015国家队论文,然后发现,广义后缀自动机不就是把很多串的SAM建到了一个SAM上,建每个串的时候都从root开始(last=root)就行了........
广义后缀自动机是Trie树的后缀自动机,可以解决多主串问题
这样的在线构造算法复杂度为O(G(T)),G(T)为Trie树上所有叶子节点深度和,发现G(T)<=所有主串总长度
还有一种离线算法,复杂度O(|T||A|) ,不学了吧
 
对于本题,建出广义SAM后,只要得到每个状态出现在不同串中的次数就好做了
我们跑每个子串,然后更新状态
状态维护cou和cur分别为出现次数及上一次出现是哪个串,然后就可以不重复的统计啦
出现次数向父亲传递,所以要沿着Parent向上跑更新,遇到cur=当前串的就不用继续跑了,这样最坏情况下复杂度为O(L^3/2),发生在n=L的时候(均值不等式啊)
 
剩下的只要DP出f[i]为i及其Parent祖先出现次数>=k有多少字符串(注意一个状态贡献的字符串为t[par].val-t[u].val),然后在跑一遍每个字符串得到答案就行了
 
注意sz也要=1啊啊啊啊啊啊啊啊啊再让你作死写新模板
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;
const int N=2e5+;
typedef long long ll;
int n,k;
string s[N>>];
char ss[N>>];
struct node{
int ch[],par,val;
int cou,cur;
}t[N];
int sz=,root=,last=;
void extend(int c){
int p=last,np=++sz;
t[np].val=t[p].val+;
for(;p&&!t[p].ch[c];p=t[p].par) t[p].ch[c]=np;
if(!p) t[np].par=root;
else{
int q=t[p].ch[c];
if(t[q].val==t[p].val+) t[np].par=q;
else{
int nq=++sz;
t[nq]=t[q];t[nq].val=t[p].val+;
t[q].par=t[np].par=nq;
for(;p&&t[p].ch[c]==q;p=t[p].par) t[p].ch[c]=nq;
}
}
last=np;
}
int c[N],a[N];
ll f[N];
void RadixSort(){
for(int i=;i<=sz;i++) c[t[i].val]++;
for(int i=;i<=sz;i++) c[i]+=c[i-];
for(int i=sz;i>=;i--) a[c[t[i].val]--]=i;
}
void solve(){
int u;ll ans;
for(int i=;i<=n;i++){//printf("i %d\n",i);
u=root;
for(int j=;j<s[i].size();j++){
u=t[u].ch[s[i][j]-'a'];//printf("u %d %d %d\n",u,t[u].cou,j);
int p=u;
for(;p&&t[p].cur!=i;p=t[p].par) t[p].cou++,t[p].cur=i;
}
}
RadixSort();
for(int i=;i<=sz;i++) u=a[i];
t[].cou=;
for(int i=;i<=sz;i++) u=a[i],f[u]=f[t[u].par]+(t[u].cou>=k?t[u].val-t[t[u].par].val:);
for(int i=;i<=n;i++){
u=root;ans=;
for(int j=;j<s[i].size();j++){
u=t[u].ch[s[i][j]-'a'];
ans+=f[u];
}
printf("%lld ",ans);
}
}
int main(){
freopen("in","r",stdin);
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
scanf("%s",ss),s[i]=string(ss);
last=root;
for(int j=;j<s[i].size();j++) extend(s[i][j]-'a');
}
solve();
}
 
 
 
 
 
 
 
 
 
 
 

BZOJ 3473: 字符串 [广义后缀自动机]的更多相关文章

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

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

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

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

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

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

  4. BZOJ 3277 串 (广义后缀自动机)

    3277: 串 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 309 Solved: 118 [Submit][Status][Discuss] De ...

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

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

  6. BZOJ 2894: 世界线 广义后缀自动机

    Code: #include<bits/stdc++.h> #define maxn 300000 #define ll long long using namespace std; ve ...

  7. bzoj 3926 转换+广义后缀自动机

    思路:重点在于叶子节点只有20个,我们把叶子节点提到根,把20个trie图插入后缀自动机,然后就是算有多少个本质不同的字串. #include<bits/stdc++.h> #define ...

  8. BZOJ 4180: 字符串计数 后缀自动机 + 矩阵乘法 + 二分(神题)

    Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999.   他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C ...

  9. BZOJ3473 字符串 广义后缀自动机

    今天主攻了下SAM 好多东西以前都没理解到 对于这道题 我们建一个自动机存所有串 每个穿last从1开始 对于自动机上每个点额外记一个cnt 表示能匹配到这个点的不同串个数 建完对每个串在自动机上匹配 ...

随机推荐

  1. flume1.8 开发指南学习感悟

    概述: Apache Flume是一个分布式.可用的系统,用于从许多不同的sources有效的收集并移动大量日志数据用于集中存储数据. 架构及数据流动模型: flume实际上就是一个Agent.Age ...

  2. Python 3 利用 Dlib 19.7 实现人脸识别和剪切

    0.引言 利用python开发,借助Dlib库进行人脸识别,然后将检测到的人脸剪切下来,依次排序显示在新的图像上: 实现的效果如下图所示,将图1原图中的6张人脸检测出来,然后剪切下来,在图像窗口中依次 ...

  3. 自己实现一个each迭代器

    什么是迭代器? 其实就是对一个对象内部进行遍历的方法,比如jquery的each方法,或者原生js的foreach方法. 迭代器的特点 针对迭代器,这里有几个特点: ☑ 访问一个聚合对象的内容而无需暴 ...

  4. Micropython TPYBoard 智能温控小风扇资料分享

    南方都下大雪了,苦逼的北方还没下雪,天寒地冻,不过这几天办公室空调开太大了就想到做一个温控小风扇,简单模型出来了.等夏天一定做一个美观精致的小风扇送给女朋友(如果有的话QAQ)话不多说直接上干货.(跪 ...

  5. 什么是MVC ?

    记得第一次面试phper(php是对我来说可以快速上手的另一web开发语言),人家问我MVC,我只知道m就是model,v就是view,c就是Controller,具体把其它的认识我是一无所知,结果我 ...

  6. :nth-child(n)

    规定属于其父元素的第二个子元素的每个 p 的背景色: p:nth-child(2) { background:#ff0000; } 1定义和用法 :nth-child(n) 选择器匹配属于其父元素的第 ...

  7. boostrap ajax表单验证提交

    =============================================================================== 1. 1 <link href=& ...

  8. vue中组件之间的相互调用,及通用后台管理系统左侧菜单树的迭代生成

    由于本人近期开始学习使用vue搭建一个后端管理系统的前端项目,在左侧生成菜单树的时候遇到了一些问题.在这里记录下 分析:由于本人设定的菜单可以使多级结构,直接使用vue的v-for 遍历并不是很方便. ...

  9. 主页面刷新 illegalStateException:stream

    其实是:jsonmappingexception:no serializer found for class 由于后台错误堆栈打印很快,只看到illegalStateException:stream ...

  10. python_5_模块

    创:5_4_2017 修: 什么是模块? --标准库+第三方库+自定义,为实现某一方面的功能集合(变量,函数,类) 如何安装第三方库? --pip install 第三方库 如何导入和使用模块? -- ...