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 ...
随机推荐
- 使用webgl(three.js)搭建一个3D智慧园区、3D建筑,3D消防模拟,web版3D,bim管理系统——第四课
序:这段时间忙于奔波,好久没有更新了,今天更新一下,继续上节课的完善讲解,算是对前段时间的一个总结吧.披星戴月的时光也算有点应用效果了. 对于webgl(three.js)性能这一块我在上节课< ...
- YII框架路由配置
首先要在服务器配置(httpd.conf)中开启重写模块: #开启重写模块,将其前面的#去掉 LoadModule rewrite_module modules/mod_rewrite.so #Dir ...
- Change - Why we need coding standards
Change - Why we need coding standards I have the idea of coding standards when I have to review my t ...
- 送专利啦~~ .Net高阶异常处理之TopLevelEH
我们知道,.Net的应用程序运行在.net framework虚拟机上,对于在运行时发生的错误,我们有try...catch可以捕捉,实在不济,对于winform和asp.net 我们都有全局的事件可 ...
- 微信小程序整理
目录 开发环境 目录结构 WXML组件 WXSS 数据绑定 条件渲染 列表渲染 模版 事件 引用 路由传参 API 实例TodoList 1.开发环境 开发工具下载(https://mp.weixin ...
- 使用OpenSSL(Windows x64版)将pem格式证书转换为p12格式
今天同事遇到一个问题,他获得的证书只有pem格式,而服务器要求提交p12格式,一时搞不定,来找我帮忙. 我之前也从未接触过证书类型的转换,所以上网大致搜索了一下,又亲自动手试了试,现将有关心得经验记录 ...
- Spring相关概念的理解理解
spring 框架的优点是一个轻量级比较简单易学的框架,实际使用中的有点优点有哪些呢!1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3 ...
- mysql根据时间查询日期的优化
例如查询昨日新注册用户,写法有如下两种: EXPLAIN select * from chess_user u where DATE_FORMAT(u.register_time,'%Y-%m-%d' ...
- Java温故而知新(3)异常处理机制
异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出 ...
- 第十三章.MySQL数据库与JDBC编程(下)
JDBC的典型用法: JDBC4.2常用接口和类简介: DriverManager:用于管理JDBC驱动的服务类,程序中使用该类的主要功能是获取Connection对象,该类包含如下方法: publi ...