【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】字符串识别(后缀自动机)的更多相关文章

  1. BZOJ1396 识别子串 和 BZOJ2865 字符串识别

    字符串识别 2865: 字符串识别 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 839  Solved: 261[Submit][Status][D ...

  2. bzoj2865 字符串识别

    Description XX在进行字符串研究的时候,遇到了一个十分棘手的问题. 在这个问题中,给定一个字符串S,与一个整数K,定义S的子串T=S(i, j)是关于第K位的识别子串,满足以下两个条件: ...

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

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

  4. 51nod1469 淋漓字符串(后缀自动机)

    题目大意: 首先,我们来定义一下淋漓尽致子串. 1.令原串为S. 2.设子串的长度为len,在原串S中出现的次数为k,令其出现的位置为p1, p2, ....pk(即这个子串在原串中[pi,pi + ...

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

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

  6. 【BZOJ4556】[TJOI2016&HEOI2016] 字符串(后缀自动机+线段树合并+二分)

    点此看题面 大致题意: 给你一个字符串\(s\),每次问你一个子串\(s[a..b]\)的所有子串和\(s[c..d]\)的最长公共前缀. 二分 首先我们可以发现一个简单性质,即要求最长公共前缀,则我 ...

  7. 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)

    题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...

  8. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

  9. 字符串(后缀自动机):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 ...

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

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

随机推荐

  1. python基础——字符串

    Python的核心数据类型--字符串 常见字符串常量和表达式 操作 解释 s = '' 空字符串 s = "dodo's" 双引号和单引号 s = 'd\no\p\td\x00o' ...

  2. mono for andorid第一个小应用

    先上图 这个小应用根据两人的姓名算出两人的关系,当然仅仅娱乐. 本来想多写写,但是实在觉得没什么可写的,而且本人正处于感冒状态,脑袋不怎么灵光,所以就不写那么多废话了. 安装mono的话,就上吾乐吧软 ...

  3. 视觉SLAM中的深度估计问题

    一.研究背景 视觉SLAM需要获取世界坐标系中点的深度. 世界坐标系到像素坐标系的转换为(深度即Z): 深度的获取一共分两种方式: a)主动式 RGB-D相机按照原理又分为结构光测距.ToF相机 To ...

  4. Python数据可视化的10种技能

    今天我来给你讲讲Python的可视化技术. 如果你想要用Python进行数据分析,就需要在项目初期开始进行探索性的数据分析,这样方便你对数据有一定的了解.其中最直观的就是采用数据可视化技术,这样,数据 ...

  5. Python字符串/元祖/列表/字典互转

    #-*- coding:UTF-8 -*- #author:RXS002 #1.字典 dict = {'name':'Zara','age':7,'class':'First'} #字典转换为字符串, ...

  6. Machine Learning笔记整理 ------ (一)基本概念

    机器学习的定义:假设用P来评估计算机程序在某任务类T上的性能,若一个程序通过利用经验E,使其在T中任务获得了性能改善,我们则说关于任务类T和P,该程序对经验E进行了学习(Mitchell, 1997) ...

  7. sql脚本创建用户角色权限表

    /******************************************/ /* 名称:权限管理 */ /* 编写日期:2010.5.20 */ /* 开发者:dangqinghua * ...

  8. 微软职位内部推荐-Senior Software Engineer II-Sharepoint

    微软近期Open的职位: SharePoint is a multi-billion dollar enterprise business that has grown from an on-prem ...

  9. asp.net mvc 使用Ajax调用Action 返回数据【转】

      使用asp.net mvc 调用Action方法很简单. 一.无参数方法. 1.首先,引入jquery-1.5.1.min.js 脚本,根据版本不同大家自行选择. <script src=& ...

  10. 互评Alpha版本——基于spec评论作品

    组名:可以低头,但没必要 组长:付佳 组员:张俊余  李文涛  孙赛佳  田良  于洋  刘欣  段晓睿 一.二次元梦之队----I DO 在测评该项目时,我们组索要了该组的apk程序,安装之后我就开 ...