BZOJ1396:识别子串(SAM)
Description

Input
Output
Sample Input
Sample Output
1
2
3
3
2
2
3
3
2
2
3
3
2
1
2
3
3
2
1
2
3
4
Solution
1A挺开心的省得调了
对于SAM上的每一个节点,我们只需要考虑right集合大小为1的
设一个right集合大小为1的点结束点在endpos,有效长度为[l,r]
那么对于区间[endpos-r+1,endpos-l+1],这个点的贡献为endpos-i+1,用一颗线段树维护endpos+1,i最后计算贡献
对于区间[endpos-l+1,endpos],这个点的贡献为l,再开一颗线段树维护l
最后扫一遍单点查询最小值就好了
标记永久化好像非常短还好写= =
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#define N (200000+1000)
using namespace std; char s[N];
int Ans,n; struct SGT
{
int Segt[N<<];
SGT(){memset(Segt,0x7f,sizeof(Segt));} void Update(int now,int l,int r,int l1,int r1,int k)
{
if (r<l1 || l>r1) return;
if (l1<=l && r<=r1){Segt[now]=min(Segt[now],k);return;}
int mid=(l+r)>>;
Update(now<<,l,mid,l1,r1,k); Update(now<<|,mid+,r,l1,r1,k);
}
void Query(int now,int l,int r,int x)
{
Ans=min(Ans,Segt[now]);
if (l==r) return;
int mid=(l+r)>>;
if (x<=mid) Query(now<<,l,mid,x);
else Query(now<<|,mid+,r,x);
}
}SGT[]; struct SAM
{
int fa[N],son[N][],right[N],step[N],End[N],od[N],wt[N];
int p,q,np,nq,last,cnt;
SAM(){last=++cnt;} void Insert(int x,int pos)
{
p=last; last=np=++cnt; step[np]=step[p]+; right[np]=; End[np]=pos;
while (p && !son[p][x]) son[p][x]=np,p=fa[p];
if (!p) fa[np]=;
else
{
q=son[p][x];
if (step[p]+==step[q]) fa[np]=q;
else
{
nq=++cnt; step[nq]=step[p]+;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
while (son[p][x]==q) son[p][x]=nq,p=fa[p];
}
}
}
void Init()
{
int len=strlen(s+);
for (int i=; i<=cnt; ++i) wt[step[i]]++;
for (int i=; i<=len; ++i) wt[i]+=wt[i-];
for (int i=cnt; i>=; --i) od[wt[step[i]]--]=i;
for (int i=cnt; i>=; --i) right[fa[od[i]]]+=right[od[i]];
}
void Solve()
{
for (int i=; i<=cnt; ++i)
if (right[i]==)
{
SGT[].Update(,,n,End[i]-step[i]+,End[i]-step[fa[i]],End[i]+);
SGT[].Update(,,n,End[i]-step[fa[i]],End[i],step[fa[i]]+);
}
for (int i=; i<=n; ++i)
{
Ans=0x7fffffff;
SGT[].Query(,,n,i); Ans-=i;
SGT[].Query(,,n,i);
printf("%d\n",Ans);
}
}
}SAM; int main()
{
scanf("%s",s+);
n=strlen(s+);
for (int i=; i<=n; ++i)
SAM.Insert(s[i]-'a',i);
SAM.Init();
SAM.Solve();
}
BZOJ1396:识别子串(SAM)的更多相关文章
- BZOJ1396 识别子串【SAM+SegmentTree】
BZOJ1396 识别子串 给定一个串\(s\),对于串中的每个位置,输出经过这个位置且只在\(s\)中出现一次的子串的最短长度 朴素的想法是,我们要找到那些只出现一次的子串,之后遍历每个串,把串所覆 ...
- BZOJ-1396: 识别子串
后缀自动机+线段树 先建出\(sam\),统计一遍每个点的\(right\)集合大小\(siz\),对于\(siz=1\)的点\(x\),他所代表的子串只会出现一次,设\(y=fa[x]\),则这个点 ...
- BZOJ1396 识别子串 和 BZOJ2865 字符串识别
字符串识别 2865: 字符串识别 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 839 Solved: 261[Submit][Status][D ...
- 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 ...
- BZOJ1396 识别子串 字符串 SAM 线段树
原文链接http://www.cnblogs.com/zhouzhendong/p/9004467.html 题目传送门 - BZOJ1396 题意 给定一个字符串$s$,$|s|\leq 10^5$ ...
- bzoj1396识别子串(SAM+线段树)
复习SAM板子啦!考前刷水有益身心健康当然这不是板子题/水题…… 很容易发现只在i位置出现的串一定是个前缀串.那么对答案的贡献分成两部分:一部分是len[x]-fa~len[x]的这部分贡献会是r-l ...
- BZOJ bzoj1396 识别子串
题面: bzoj1396 题解: 先建出SAM,并计算right集合大小.显然符合条件的点的right集合大小为1. 对于每个right集合为1的状态显然可以算出这些状态的pos以及maxlen和mi ...
- bzoj1396: 识别子串
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
随机推荐
- 封装常用的跨浏览器的事件对象EventUtil
var EventUtil = { addHandler: function(element,type,handler) { //事件监听 if(element.addEventListener) { ...
- angular-ui-router动态加载模块
1.定义index.html主页,对于通用的js就不用require依赖加载了,其中main.js作为主模块,用require添加系统路由模块. <!DOCTYPE html> <h ...
- 借助 CORS 从 JavaScript 使用 API 应用
应用服务提供内置的跨域资源共享 (CORS) 支持,可让 JavaScript 客户端对 API 应用中托管的 API 进行跨域调用.应用服务允许配置对 API 的 CORS 访问,无需在 API 中 ...
- 微信小程序开发框架整理
目前除了原生的微信小程序开发外,各大厂商陆续造了自己的开发框架,现整理如下: WePY 腾讯官方开源的小程序组件化开发框架,目前有15K+Star ,一直在更新着,社区活跃,掉坑能快速的找到方法爬出来 ...
- Winform DataGridView列的单元格中动态添加图片和文字
先上图在说,第二列中图片和文字的样式 1.需要重写DataGridViewTextBoxColumn,新建类TextAndImageColumn.cs using System; using Syst ...
- MongoDB 线上环境按照及配置(授权方式启动)
1创建文件repo文件 #vim /etc/yum.repos.d/mongodb-org-3.4.repo [mongodb-org-3.4] name=MongoDB Repository bas ...
- spring设置字符编码过滤器
一.在web.xml中的配置 <!-- characterEncodingFilter字符编码过滤器 --> <filter> <filter-name>chara ...
- Redis实现主从复制(Master&Slave)
由于前段时间公司项目比较赶,一直抽不出时间写博客,今天偷空写一篇吧.前面给大家讲解了单机版redis的基本操作,现在继续给大家讲解一下Redis的进阶部分,主从复制和读写分离. 一.Master&am ...
- node.js缓存处理方式
Node.JS缓存处理分为客户端和服务端两个部分. 客户端的缓存主要是利用浏览器对HTTP协议响应头中cache-control和expires字段的支持.浏览器在得到明确的响应头后,会将文件缓存在本 ...
- JBPM学习第3篇:10分钟熟悉JBPM工作台
1.打开:http://localhost:8080/jbpm-console 键入用户名和密码(krisv/krisv)登陆. 2.看视频: http://download.jboss.org/jb ...