bzoj1396识别子串(SAM+线段树)
复习SAM板子啦!考前刷水有益身心健康当然这不是板子题/水题……
很容易发现只在i位置出现的串一定是个前缀串。那么对答案的贡献分成两部分:一部分是len[x]-fa~len[x]的这部分贡献会是r-l+1;剩下一部分1~len-fa-1这部分会和i~r构成答案,写两棵线段树即可。
然后就又是板子题了,两个板子(SAM+线段树)套起来。
#include<bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int N=2e5+,inf=0x3f3f3f3f;
int n,lst=,rt=,cnt=,ch[N][],len[N],fa[N],sz[N];
char s[N];
struct tree{
int mn[N<<];
void init(){memset(mn,0x3f,sizeof mn);}
void pushdown(int rt)
{
if(mn[rt]==inf)return;
mn[rt<<]=min(mn[rt<<],mn[rt]),mn[rt<<|]=min(mn[rt<<|],mn[rt]);
mn[rt]=inf;
}
void update(int L,int R,int v,int l,int r,int rt)
{
if(L<=l&&r<=R){mn[rt]=min(mn[rt],v);return;}
int mid=l+r>>;pushdown(rt);
if(L<=mid)update(L,R,v,lson);
if(R>mid)update(L,R,v,rson);
}
int query(int k,int l,int r,int rt)
{
if(l==r)return mn[rt];
int mid=l+r>>;pushdown(rt);
if(k<=mid)return query(k,lson);
return query(k,rson);
}
}tr1,tr2;
void build(int c)
{
int p=lst,np=++cnt;
len[np]=len[p]+,sz[np]=;
while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
if(!p)fa[np]=rt;
else{
int q=ch[p][c];
if(len[p]+==len[q])fa[np]=q;
else{
int nq=++cnt;
memcpy(ch[nq],ch[q],sizeof ch[q]);
fa[nq]=fa[q],fa[np]=fa[q]=nq,len[nq]=len[p]+;
while(p&&ch[p][c]==q)ch[p][c]=nq,p=fa[p];
}
}
lst=np;
}
int main()
{
scanf("%s",s+),n=strlen(s+);
for(int i=;i<=n;i++)build(s[i]-'a');
for(int i=;i<=cnt;i++)sz[i]=;
for(int i=;i<=cnt;i++)sz[fa[i]]=;
tr1.init(),tr2.init();
for(int i=;i<=cnt;i++)
if(sz[i]==)
{
int l=len[i]-len[fa[i]],r=len[i];
if(l>=)tr1.update(,l-,r+,,n,);
tr2.update(l,r,r-l+,,n,);
}
for(int i=;i<=n;i++)printf("%d\n",min(tr1.query(i,,n,)-i,tr2.query(i,,n,)));
}
bzoj1396识别子串(SAM+线段树)的更多相关文章
- BZOJ1396:识别子串(SAM)
Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample I ...
- BZOJ1396 识别子串【SAM+SegmentTree】
BZOJ1396 识别子串 给定一个串\(s\),对于串中的每个位置,输出经过这个位置且只在\(s\)中出现一次的子串的最短长度 朴素的想法是,我们要找到那些只出现一次的子串,之后遍历每个串,把串所覆 ...
- BZOJ1396 识别子串 和 BZOJ2865 字符串识别
字符串识别 2865: 字符串识别 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 839 Solved: 261[Submit][Status][D ...
- BZOJ1396 识别子串 字符串 SAM 线段树
原文链接http://www.cnblogs.com/zhouzhendong/p/9004467.html 题目传送门 - BZOJ1396 题意 给定一个字符串$s$,$|s|\leq 10^5$ ...
- bzoj千题计划318:bzoj1396: 识别子串(后缀自动机 + 线段树)
https://www.lydsy.com/JudgeOnline/problem.php?id=1396 后缀自动机的parent树上,如果不是叶子节点,那么至少有两个子节点 而一个状态所代表子串的 ...
- BZOJ1396: 识别子串(后缀自动机,线段树)
Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample I ...
- bzoj 1396: 识别子串【SAM+线段树】
建个SAM,符合要求的串显然是|right|==1的节点多代表的串,设si[i]为right集合大小,p[i]为right最大的r点,这些都可以建出SAM后再parent树上求得 然后对弈si[i]= ...
- BZOJ1396: 识别子串(后缀自动机 线段树)
题意 题目链接 Sol 后缀自动机+线段树 还是考虑通过每个前缀的后缀更新答案,首先出现次数只有一次,说明只有\(right\)集合大小为\(1\)的状态能对答案产生影响 设其结束位置为\(t\),代 ...
- BZOJ-1396: 识别子串
后缀自动机+线段树 先建出\(sam\),统计一遍每个点的\(right\)集合大小\(siz\),对于\(siz=1\)的点\(x\),他所代表的子串只会出现一次,设\(y=fa[x]\),则这个点 ...
随机推荐
- GIT-Linux(CentOS7)系统安装Git
GIT-Linux(CentOS7)系统安装Git 未成功 查看是否已安装了Git 发现Git版本已存在,说明已安装了Git [root@localhost ~]# rpm -qa|grep git ...
- Essay写作的灵魂:内容
在国内大家也许不觉得时常要写essay,但在国外留学,时不时就会有一篇essay写作任务下来.而时常写文的同学们应当就会知道一篇文章中的介绍和结论有多么重要,甚至于当导师拿到你的essay,如果摘要没 ...
- HZNU-ACM寒假集训Day7小结 背包DP
背包问题 01背包 状态:f(i,j) 表示只能装前i个物品的情况下,容量为j的背包所能达到的最大总价值 状态转移方程: f(i,j)=max(f(i-1,j),f(i-1,j-w[i])+v[i] ...
- Hairpin|Bulge|Loop|假结|共变化(进化)|单序列预测|snRNA|snoRNA|siRNA|microRNA|piRNA|LncRNA|antisense RNAs|cis-NATs|trans-NATs|假基因|环形RNA
生物信息学 GU也可以配对,即“wobble” pairing GU. Hairpin发夹结构,最少不能少于3个碱基.没有配对 Bulge 单侧配对 Loop双侧配对 假结,游离的leading ed ...
- part5 城市页面列表开发
1.配置路由 先在router文件夹中,创建一个路由.引入组件 { path: '/city', name: 'HelloCity', component: city, meta: { name: ' ...
- POJ 1260:Pearls 珍珠DP
Pearls Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7947 Accepted: 3949 Descriptio ...
- eclipse JSP学习遇到的问题,获取页面中文值时出现乱码
性别:男<input type="radio" name="sex" value="男" /> String sex =requ ...
- SEO初步学习之影响网站排名的因素
本文介绍一些比较明显的因素,一些隐藏较深的原因还有待发掘: 1.采集网站内容,即抄袭其他网站的内容. 2.新站上传后建议不要有大的改动. 3.标题频繁修改. 4.大量投放垃圾外链. 5.不做友链,交友 ...
- Vue.js——6.创建组件
Vue组件组件就是为了拆分Vue实例的代码量,能够不同的功能定义不同的组件创建组件的方法 1. // 创建组件 let com1=Vue.extend({ template:'<h1>he ...
- 18 11 05 继续补齐对python中的class不熟悉的地方 和 pygame 精灵
---恢复内容开始--- class game : #历史最高分----- 是定义类的属性 top_score =0 def __init__(self, player_name) : #是定义的实例 ...