复习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+线段树)的更多相关文章

  1. BZOJ1396:识别子串(SAM)

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

  2. BZOJ1396 识别子串【SAM+SegmentTree】

    BZOJ1396 识别子串 给定一个串\(s\),对于串中的每个位置,输出经过这个位置且只在\(s\)中出现一次的子串的最短长度 朴素的想法是,我们要找到那些只出现一次的子串,之后遍历每个串,把串所覆 ...

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

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

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

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

  5. bzoj千题计划318:bzoj1396: 识别子串(后缀自动机 + 线段树)

    https://www.lydsy.com/JudgeOnline/problem.php?id=1396 后缀自动机的parent树上,如果不是叶子节点,那么至少有两个子节点 而一个状态所代表子串的 ...

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

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

  7. bzoj 1396: 识别子串【SAM+线段树】

    建个SAM,符合要求的串显然是|right|==1的节点多代表的串,设si[i]为right集合大小,p[i]为right最大的r点,这些都可以建出SAM后再parent树上求得 然后对弈si[i]= ...

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

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

  9. BZOJ-1396: 识别子串

    后缀自动机+线段树 先建出\(sam\),统计一遍每个点的\(right\)集合大小\(siz\),对于\(siz=1\)的点\(x\),他所代表的子串只会出现一次,设\(y=fa[x]\),则这个点 ...

随机推荐

  1. java多线程并发(一)-- 相关基础知识

    java多线程的知识是java程序员都应该掌握的技能,目前我接触的项目上用的不多,花点时间熟悉熟悉. 一.基础知识 1.什么是进程? 进程是具有一定独立功能的正在运行过程中的程序,是操作系统进行资源分 ...

  2. 手机与Arduino蓝牙串口通讯实验及完整例程

    安卓手机与Arduino之间采用蓝牙串口通讯,是很多智能装置和互动装置常用的控制方法,简单而有效,无需网络环境,很实用的技术. 实验采用Arduino UNO板,加了一块1602LCD屏做显示(因为只 ...

  3. Unity3D一些基本的概念和一些基本操作

    场景:整个游戏由场景组成,一个游戏至少要有一个场景,如果把所有的游戏画面放在一个场景里也是可以的,如果游戏非常非常的大,如果所有的东西都放到一个场景里那么结构就不是那么清晰了而且处理起来就会麻烦一些, ...

  4. [LC] 863. All Nodes Distance K in Binary Tree

    We are given a binary tree (with root node root), a target node, and an integer value K. Return a li ...

  5. Java并发分析—synchronized

    在计算机操作系统中,并发在宏观上是指在同一时间段内,同时有多道程序在运行. 一个程序可以对应一个进程或多个进程,进程有独立的存储空间.一个进程包含一个或多个线程.线程堆空间是共享的,栈空间是私有的.同 ...

  6. 约数个数函数(d)的一个性质证明

    洛谷P3327 [SDOI2015]约数个数和 洛谷P4619 [SDOI2018]旧试题 要用到这个性质,而且网上几乎没有能看的证明,所以特别提出来整理一下. \[ d(AB) = \sum_{x| ...

  7. 计算机网络(2): http的基础上用SSL或TSL加密

    加密过程具体TCP实现 步骤 1 : 客户端通过发送Client Hello报文开始SSL通信(这里是在TCP的三次握手已经完成的基础上进行的).报文中包含客户端支持的SSL的指定版本.加密组件列表( ...

  8. Momentum

    11.6 Momentum 在 Section 11.4 中,我们提到,目标函数有关自变量的梯度代表了目标函数在自变量当前位置下降最快的方向.因此,梯度下降也叫作最陡下降(steepest desce ...

  9. 第 10 章 gdb

    一.参考网址 1.linux c编程一站式学习 二.命令列表 1.图1: 2.图2: 3.图3: 三.重点摘抄 1.断点与观测点的区别 我们知道断点是当程序执行到某一代码行时中断,而观察点是当程序访问 ...

  10. python爬虫--cookie反爬处理

    Cookies的处理 作用 保存客户端的相关状态 在爬虫中如果遇到了cookie的反爬如何处理? 手动处理 在抓包工具中捕获cookie,将其封装在headers中 应用场景:cookie没有有效时长 ...