【BZOJ1396】识别子串&【BZOJ2865】字符串识别(后缀自动机)
【BZOJ1396】识别子串&【BZOJ2865】字符串识别(后缀自动机)
题面
自从有了DBZOJ
终于有地方交权限题了
题解
很明显,只出现了一次的串
在\(SAM\)的\(right/endpos\)集合大小一定为\(1\)
换句话说,在\(parent\)树上是叶子节点
找到所有这样的节点,
假设它的\(len=r\),它父亲的\(len=p\),它的结束位置为显然就是\(r\)
令\(l=r-p\)
以\(r\)结尾,
并且只出现了一次的串的左端点
为\(1..l\),那么,他们的答案可以更新为\(r+1-i\)
剩下的位置\(l+1..r\),他们无法作为左端点,只能包含在这些串中
于是找到一个最短的包含他们的串\(S[l..r]\)
所以,这段区间的答案可以更新为\(r-l+1\)
显然不好一起维护,
于是开两棵线段树,一个维护\(r+1-i\),先不考虑\(i\),最后减去就好
另一个直接维护\(r-l+1\)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define lson (now<<1)
#define rson (now<<1|1)
#define MAX 111111
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n;
bool vis[MAX<<1];
struct SAM
{
struct Node
{
int son[26];
int ff,len;
}t[MAX<<1];
int last,tot;
void init(){last=tot=1;}
void extend(int c)
{
int p=last,np=++tot;last=np;
t[np].len=t[p].len+1;
while(p&&!t[p].son[c])t[p].son[c]=np,p=t[p].ff;
if(!p)t[np].ff=1;
else
{
int q=t[p].son[c];
if(t[q].len==t[p].len+1)t[np].ff=q;
else
{
int nq=++tot;
t[nq]=t[q];t[nq].len=t[p].len+1;
t[np].ff=t[q].ff=nq;
while(p&&t[p].son[c]==q)t[p].son[c]=nq,p=t[p].ff;
}
}
}
}SAM;
char ch[MAX];
struct SegMentTree
{
struct Node{int v;}t[MAX<<2];
void Build(int now,int l,int r)
{
t[now].v=1e9;if(l==r)return;
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
}
void puttag(int now,int w){t[now].v=min(t[now].v,w);}
void pushdown(int now)
{
if(t[now].v==1e9)return;
puttag(lson,t[now].v);puttag(rson,t[now].v);
t[now].v=1e9;
}
void Modify(int now,int l,int r,int L,int R,int w)
{
if(L>R)return;
if(L<=l&&r<=R){puttag(now,w);return;}
pushdown(now);int mid=(l+r)>>1;
if(L<=mid)Modify(lson,l,mid,L,R,w);
if(R>mid)Modify(rson,mid+1,r,L,R,w);
}
int Query(int now,int l,int r,int p)
{
if(l==r)return t[now].v;
pushdown(now);int mid=(l+r)>>1;
if(p<=mid)return Query(lson,l,mid,p);
else return Query(rson,mid+1,r,p);
}
}A,B;
int main()
{
SAM.init();
scanf("%s",ch+1);n=strlen(ch+1);
for(int i=1;i<=n;++i)SAM.extend(ch[i]-97);
for(int i=1;i<=SAM.tot;++i)vis[SAM.t[i].ff]=true;
A.Build(1,1,n);B.Build(1,1,n);
for(int i=1;i<=SAM.tot;++i)
if(!vis[i])
{
int l=SAM.t[i].len-SAM.t[SAM.t[i].ff].len,r=SAM.t[i].len;
A.Modify(1,1,n,l,r,r-l+1);
B.Modify(1,1,n,1,l-1,r+1);
}
for(int i=1;i<=n;++i)
printf("%d\n",min(A.Query(1,1,n,i),B.Query(1,1,n,i)-i));
return 0;
}
【BZOJ1396】识别子串&【BZOJ2865】字符串识别(后缀自动机)的更多相关文章
- BZOJ1396 识别子串 和 BZOJ2865 字符串识别
字符串识别 2865: 字符串识别 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 839 Solved: 261[Submit][Status][D ...
- bzoj2865 字符串识别
Description XX在进行字符串研究的时候,遇到了一个十分棘手的问题. 在这个问题中,给定一个字符串S,与一个整数K,定义S的子串T=S(i, j)是关于第K位的识别子串,满足以下两个条件: ...
- BZOJ 3473: 字符串 [广义后缀自动机]
3473: 字符串 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 354 Solved: 160[Submit][Status][Discuss] ...
- 51nod1469 淋漓字符串(后缀自动机)
题目大意: 首先,我们来定义一下淋漓尽致子串. 1.令原串为S. 2.设子串的长度为len,在原串S中出现的次数为k,令其出现的位置为p1, p2, ....pk(即这个子串在原串中[pi,pi + ...
- 【bzoj3277/bzoj3473】串/字符串 广义后缀自动机
题目描述 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). 输入 第一行两个整数n,k.接下来n行每行一个 ...
- 【BZOJ4556】[TJOI2016&HEOI2016] 字符串(后缀自动机+线段树合并+二分)
点此看题面 大致题意: 给你一个字符串\(s\),每次问你一个子串\(s[a..b]\)的所有子串和\(s[c..d]\)的最长公共前缀. 二分 首先我们可以发现一个简单性质,即要求最长公共前缀,则我 ...
- 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)
题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...
- [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增
题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...
- 字符串(后缀自动机):Codeforces Round #129 (Div. 1) E.Little Elephant and Strings
E. Little Elephant and Strings time limit per test 3 seconds memory limit per test 256 megabytes inp ...
- bzoj 3277: 串 & bzoj 3473: 字符串【后缀自动机||后缀数组】
建一个广义后缀自动机(每加完一个串都返回root),在parent树上dpsum记录合法长度,打着时间戳往上跳,最后每个串在自动机上跑一变统计答案即可. 后缀数组理解起来可能方便一点,但是难写,就只说 ...
随机推荐
- 一个经典的PHP加密解密算法authcode
项目中有时我们需要使用PHP将特定的信息进行加密,也就是通过加密算法生成一个加密字符串,这个加密后的字符串可以通过解密算法进行解密,便于程序对解密后的信息进行处理.最常见的应用在用户登录以及一些API ...
- HIS系统患者实体OO设计的一点思考
软件开发的生命周期中,数据库建模后,在某个数据库系统中形成相对应的表,之后再根据数据库模型设计相关的业务对象及其关系.这其实是进行了两次设计,一次是数据库模型设计,数据库模型设计是根据现实业务提取出来 ...
- 「日常训练」The Necklace(UVA-10054)
代码 for(int i=0; i!=n; ++i) { int u = cin.nextInt(); int v = cin.nextInt(); edges.add(new Edge(u,v)); ...
- java 中的字符串
创建String对象 String s1="xxx"://创建一个字符串对象“xxx”,名为s1; String s2=new String();//创建一个空字符串对象,名为S2 ...
- Elastic-Job 分布式调度平台
概述 referred:http://elasticjob.io/docs/elastic-job-lite/00-overview Elastic-Job是一个分布式调度解决方案,由两个相互独立的子 ...
- 时序数据库InfluxDB
在系统服务部署过后,线上运行服务的稳定性是系统好坏的重要体现,监控系统状态至关重要,经过调研了解,时序数据库influxDB在此方面表现优异. influxDB介绍 时间序列数据是以时间字段为每行数据 ...
- 算法工程师进化-NLP之主题模型
1 引言 主题模型是文本挖掘的重要工具,近年来在学术界和工业届都获得了非常多的关注.学术界的工作主要集中在建模层面,即提出各种各样的主题模型来适应不同的场景,因此缺乏指导主题模型在工业场景落地的资源和 ...
- 根据Unicode码生成汉字
最近需要一批汉字字符数据,类似数字字符与ASCII码之间的对应关系,汉字字符与Unicode码之间也存在对应关系. 所以可以遍历Unicode码批量生成汉字. 其中,汉字为宽字符,输出时候注意需要修改 ...
- Scrum立会报告+燃尽图 05
此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2195] 一.小组介绍 组长:王一可 组员:范靖旋,王硕,赵佳璐,范洪达 ...
- 定制自己的动画 View 控件(Canvas 使用)
定制自己的动画 View 控件(Canvas 使用) 如果要定义自己的 View 控件,则需要新建一个类继承 android.view.View.然后在 onDraw 中写自己需要实现的方式. 这里定 ...