题意:

一行,一个由小写字母组成的字符串S,长度不超过10^5

思路:论文题

设p为自动机上的合法结点,r为右端点,len=st[fa[p]]]+1

位置[r-st[p]+1,r-len+1]与r-i+1取min,其中i为下标

位置[r-len+1,r]与len取min

建立两棵线段树,分别维护r+1和len

因为只有区间修改和单点查询可以不写lazytag

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,int>P;
#define N 100010
#define M 210000
#define fi first
#define se second
#define MP make_pair
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const int MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int INF=1e9;
ll inf=5e13;
int dx[]={-,,,};
int dy[]={,,-,}; char s[N];
int p,np,q,nq,k,cas,n;
int t[N<<][]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void build(int l,int r,int p,int op)
{
t[p][op]=INF;
if(l==r) return;
int mid=(l+r)>>;
build(l,mid,ls,op);
build(mid+,r,rs,op);
} void update(int l,int r,int x,int y,int v,int p,int op)
{
if(x<=l&&r<=y)
{
t[p][op]=min(t[p][op],v);
return;
}
int mid=(l+r)>>;
if(x<=mid) update(l,mid,x,y,v,ls,op);
if(y>mid) update(mid+,r,x,y,v,rs,op);
} int query(int l,int r,int x,int p,int op)
{
if(l==r) return t[p][op];
int mid=(l+r)>>;
if(x<=mid) return min(t[p][op],query(l,mid,x,ls,op));
else return min(t[p][op],query(mid+,r,x,rs,op));
} struct sam
{
int cnt;
int fa[N<<],ch[N<<][];
int st[N<<],b[N<<],bl[N<<],to[N<<],size[N<<]; sam()
{
cnt=np=;
} void add(int x,int i)
{
p=np; st[np=++cnt]=st[p]+;
to[np]=i;
while(p&&!ch[p][x])
{
ch[p][x]=np;
p=fa[p];
}
if(!p) fa[np]=;
else if(st[p]+==st[q=ch[p][x]]) fa[np]=q;
else
{
st[nq=++cnt]=st[p]+;
memcpy(ch[nq],ch[q],sizeof ch[q]);
//t[nq]=t[q];
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
while(p&&ch[p][x]==q)
{
ch[p][x]=nq;
p=fa[p];
}
}
} void solve()
{
rep(i,,cnt) b[st[i]]++;
rep(i,,cnt) b[i]+=b[i-];
rep(i,,cnt) bl[b[st[i]]--]=i;
int u=;
rep(i,,n)
{
u=ch[u][s[i]-'a'];
size[u]++;
}
build(,n,,);
build(,n,,);
per(i,cnt,) size[fa[bl[i]]]+=size[bl[i]]; rep(i,,cnt)
{
int p=bl[i];
if(size[p]>) continue;
int len=st[fa[p]]+,r=to[p];
update(,n,r-len+,r,len,,);
update(,n,r-st[p]+,r-len+,r+,,);
} rep(i,,n)
{
int t1=query(,n,i,,),t2=-i+query(,n,i,,);
printf("%d\n",min(t1,t2));
} }
}sam; int main()
{
scanf("%s",s+);
n=strlen(s+);
rep(i,,n) sam.add(s[i]-'a',i);
sam.solve();
return ;
}

【BZOJ1396】识别子串(后缀自动机,线段树)的更多相关文章

  1. BZOJ1396: 识别子串(后缀自动机 线段树)

    题意 题目链接 Sol 后缀自动机+线段树 还是考虑通过每个前缀的后缀更新答案,首先出现次数只有一次,说明只有\(right\)集合大小为\(1\)的状态能对答案产生影响 设其结束位置为\(t\),代 ...

  2. 【BZOJ1396】识别子串 - 后缀自动机+线段树

    题意: Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. 题解: ...

  3. bzoj1396&&2865 识别子串 后缀自动机+线段树

    Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample Input agoodco ...

  4. BZOJ 1396&&2865 识别子串[后缀自动机 线段树]

    Description 在这个问题中,给定一个字符串S,与一个整数K,定义S的子串T=S(i, j)是关于第K位的识别子串,满足以下两个条件: 1.i≤K≤j. 2.子串T只在S中出现过一次. 例如, ...

  5. BZOJ 1396 识别子串 (后缀自动机+线段树)

    题目大意: 给你一个字符串S,求关于每个位置x的识别串T的最短长度,T必须满足覆盖x,且T在S中仅出现一次 神题 以节点x为结尾的识别串,必须满足它在$parent$树的子树中只有一个$endpos$ ...

  6. bzoj 1396/2865: 识别子串 后缀自动机+线段树

    水水的字符串题 ~ #include <map> #include <cstdio> #include <cstring> #include <algorit ...

  7. BZOJ 1396: 识别子串( 后缀数组 + 线段树 )

    这道题各位大神好像都是用后缀自动机做的?.....蒟蒻就秀秀智商写一写后缀数组解法..... 求出Height数组后, 我们枚举每一位当做子串的开头. 如上图(x, y是height值), Heigh ...

  8. BZOJ1396 识别子串 字符串 SAM 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/9004467.html 题目传送门 - BZOJ1396 题意 给定一个字符串$s$,$|s|\leq 10^5$ ...

  9. 2018.12.23 bzoj2865&&1396: 字符串识别(后缀自动机+线段树)

    传送门 卡空间差评! 题意简述:给一个字串,对于每个位置求出经过这个位置且只在字串中出现一次的子串的长度的最小值. 解法:先建出samsamsam,显然只有当sizep=1size_p=1sizep​ ...

  10. bzoj1396识别子串(SAM+线段树)

    复习SAM板子啦!考前刷水有益身心健康当然这不是板子题/水题…… 很容易发现只在i位置出现的串一定是个前缀串.那么对答案的贡献分成两部分:一部分是len[x]-fa~len[x]的这部分贡献会是r-l ...

随机推荐

  1. JS-DOM Event

    DOM Level 0 Events:绑定到 DOM 的属性上,找不到官方文档 DOM0 是在 W3C 进行标准备化之前出现的,实际上是未形成标准的试验性质的初级阶段的 DOM. var tdiv = ...

  2. pycharm项目代码上传远程centos服务器

    pycharm项目代码上传远程centos服务器 在工作中,我们经常会遇到如下情况,在windows系统下的pycharm中开发项目,但是需要在linux服务器上部署和运行我们的项目.那么我们的项目是 ...

  3. 测开之路七十:监控平台之html

    监控平台的html <!-- 继承base模板 -->{% extends "base.html" %} <!-- 引入bootstrap-datetimepic ...

  4. stl vector创建二维数组

    vector<vector<); for (auto it = v.begin(); it != v.end(); it++) { ; (*it).reserve();//预留空间为5,但 ...

  5. 应用安全 - Web安全 - 文件包含攻防

    LFI - 无限制本地文件包含 通过目录遍历漏洞可以获取到系统中其他文件的内容 常见的敏感信息路径 Windows系统 c:\boot.ini // 查看系统版本 c:\windows\system3 ...

  6. python中函数的嵌套和作用域链

    1.三元运算if条件成立的结果 if 条件 else 条件不成立的结果例如: a=20 b=10 c=a if a>b else b print(c) 2.命名空间 全局命名空间:创建的存储“变 ...

  7. MySQL集群(PXC)入门

    一.学习动机 伴随互联网行业的兴起,越来越多的领域需要相应的技术方案,比如:打出软件.电商平台.直播平台.电子支付.媒体社交. 身边常见的,校园出成绩那一年,我们会感觉网站异常的卡顿,因为访问人数太多 ...

  8. css中word-break、word-wrap和white-space的区别

    css中word-break.word-wrap和white-space的区别 :https://baijiahao.baidu.com/s?id=1578623236521030997&wf ...

  9. [Bzoj1014][JSOI2008]火星人prefix(无旋Treap&hash)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 因为涉及到增加和修改,所以后缀数组就被pass掉了,想到的就是平衡树维护hash值 ...

  10. 进程池和multiprocess.Pool模块

    一.为什么要有进程池 首先,创建进程需要消耗时间,销毁进程也需要时间.其次,即使开启了成千上万的进程,操作系统也不能让它们同时执行,这样反而会影响程序的效率.因此我们不能无限制的根据任务开启或者结束进 ...