【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记录合法长度,打着时间戳往上跳,最后每个串在自动机上跑一变统计答案即可. 后缀数组理解起来可能方便一点,但是难写,就只说 ...
随机推荐
- 一个IP可以登几个拼多多后台 拼多多如何推广营销
想要在拼多多上开双店?担心一根网线会引起IP冲突?那么一根网线可以登几个拼多多后台呢?有数据显示,挂双店是没有问题的,甚至可以多开.那么解决了一根网线的事情,要怎么对自己的店铺进行营销推广呢?下面是小 ...
- Unity编辑器扩展 Chapter3--Create Custom Inspector
一.Create Custom Inspector 重绘inspector面板一方面是我们的挂在脚本的窗口变得友好,另一方面可以让其变得更强大,比如添加一些有效性验证. 二.重要说明 1.Editor ...
- 【转】: 塞尔达组在GDC2017演讲的文字翻译:显示的力量
塞尔达系列推出新作的时候,美术风格都有明显变化.本作的风格比起写实,笔触轻快变化幅度大是其特征.2011年公开的技术演示中,画面风格要更加写实.最终版则更接近于卡通.5年里到底发生了什么呢? ▲2 ...
- 账号被锁无法ssh登陆
Account locked due to failed logins 方法一: 使用root用户登陆后执行: pam_tally2 --user=username --reset 方法二: user ...
- Loadrunner教程--常用操做流程
1loadrunner压力测试一般使用流程 1.1loadrunner压力测试原理 本质就是在loadrunner上模拟多个用户同时按固定行为访问web站点.其中固定行为在loadrunner中是通过 ...
- DruidDataSource源码分析
最近公司要求基于阿里的DruidDataSource来做一个连接池监控 , 正好之前没有看过DruidDataSource的源码 , 便自己看了四个多小时写了一些自己的理解 , 给大家分享一下 , 如 ...
- 亚马逊首次推出卖家APP 可掌握商品盈利状况
美国零售巨头亚马逊近日首次对外发布了第一款针对卖家和商户的客户端,帮助他们更加高效的管理商品和销售数据. 据美国科技新闻网站 Mashable 报道,之前亚马逊在商户移动客户端方面一直空缺,许多商户不 ...
- ES6的新特性(14)——Iterator 和 for...of 循环
Iterator 和 for...of 循环 Iterator(遍历器)的概念 JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Ma ...
- Python数据挖掘学习路程--起步
一.首先第一步我去了解了Python开发环境:Python(程序运行基础的解释器)+第三方类库(功能扩展)+编辑器(提高代码编辑效率) 编辑器有:Pycharm.Spyder.jupyter note ...
- Spring学习(五)——Spring注解(一)
---恢复内容开始--- 概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射 ...