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. Centos7搭建Confluence破解版

    Confluence破解版 应用环境: Confluence是一个专业的企业知识管理与协同软件,也可以用于构建企业wiki.通过它可以实现团队成员之间的协作和知识共享. 系统及安装软件 centos7 ...

  2. 机器学习笔记5-Tensorflow高级API之tf.estimator

    前言 本文接着上一篇继续来聊Tensorflow的接口,上一篇中用较低层的接口实现了线性模型,本篇中将用更高级的API--tf.estimator来改写线性模型. 还记得之前的文章<机器学习笔记 ...

  3. TypeScript笔记 1--环境搭建

    TypeScript是什么 Typescript是JavaScript的超集,支持ES6特性并且提供了类型系统,可以编译成Javascript.是微软开发且已经在github上开源. ES6(ES20 ...

  4. 01 mysql的安装(windows)

    在安装mysql之前,一般是先下载mysql,推荐大家去Oracle的官网下载,而且尽量使用免安装的版本(即压缩版,解压之后就可以使用的版本,不是.exe的安装版本),因为安装版的mysql在安装过程 ...

  5. CentOS 6.*通过yum安装 MySQL-5.5

    转自https://www.cnblogs.com/wsl222000/p/5445768.html 1.安装mysql-5.5的yum源 rpm -ivh http://repo.mysql.com ...

  6. Python3 字符串格式化

    1.字符串的格式化: 按照统一的规格去输出成为一个新的字符串 2.字符串格式化的方法: 1)format方法 fomat()有两个参数位置参数和关键字参数用中括号括起来{ } #{0}{1}为位置参数 ...

  7. dedecms_分页技术

    <ul>{dede:list pagesize='30'} <li><a href="[field:arcurl/]">[field:title ...

  8. CCF系列之模板生成系统( 201509-3 )

    试题名称: 模板生成系统 试题编号: 201509-3 时间限制: 1.0s 内存限制: 256.0MB 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的 ...

  9. [one day one question] nodejs require 缓存,无法检测文件变化

    问题描述: nodejs require 缓存,无法检测文件变化,当文件require引入后,当文件发生变动后即使再次使用require,返回的依然是第一次引入的文件内容,这怎么破? 解决方案: de ...

  10. JavaScript ECMAScript版本介绍

    1. 介绍 1.1 什么是ECMAScript ECMAScript,简称ES,是由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers ...