水水的字符串题 ~

#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define M 500003
#define N 1000003
#define lson now<<1
#define rson now<<1|1
#define inf 1000000000
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
int last,tot;
char str[N];
int rk[N],tax[N],A[N],minn[M<<2],minn2[M<<2];
struct data
{
int pre,cnt,len,id;
map<int,int>ch;
}t[N];
void Init() { last=tot=1; }
void extend(int c,int pos)
{
int np=++tot,p=last;
t[np].len=t[p].len+1,last=np;
for(;p&&!t[p].ch[c];p=t[p].pre) t[p].ch[c]=np;
if(!p) t[np].pre=1;
else
{
int q=t[p].ch[c];
if(t[q].len==t[p].len+1) t[np].pre=q;
else
{
int nq=++tot;
t[nq].len=t[p].len+1;
t[nq].id=t[q].id;
t[nq].ch=t[q].ch;
t[nq].pre=t[q].pre,t[q].pre=t[np].pre=nq;
for(;p&&t[p].ch[c]==q;p=t[p].pre) t[p].ch[c]=nq;
}
}
++t[np].cnt;
t[np].id=pos;
}
void build(int l,int r,int now)
{
minn[now]=minn2[now]=inf;
if(l==r) return;
int mid=(l+r)>>1;
if(l<=mid) build(l,mid,lson);
if(r>mid) build(mid+1,r,rson);
}
void update(int l,int r,int now,int L,int R,int v)
{
if(l>=L&&r<=R)
{
minn[now]=min(minn[now], v);
return;
}
int mid=(l+r)>>1;
if(L<=mid) update(l,mid,lson,L,R,v);
if(R>mid) update(mid+1,r,rson,L,R,v);
}
int query(int l,int r,int now,int p)
{
if(l==r) return minn[now];
int mid=(l+r)>>1,re=minn[now];
if(p<=mid) re=min(re, query(l,mid,lson,p));
else re=min(re, query(mid+1,r,rson,p));
return re;
}
void update2(int l,int r,int now,int L,int R,int v)
{
if(l>=L&&r<=R)
{
minn2[now]=min(minn2[now], v);
return;
}
int mid=(l+r)>>1;
if(L<=mid) update2(l,mid,lson,L,R,v);
if(R>mid) update2(mid+1,r,rson,L,R,v);
}
int query2(int l,int r,int now,int p)
{
if(l==r) return minn2[now];
int mid=(l+r)>>1, re=minn2[now];
if(p<=mid) re=min(re,query2(l,mid,lson,p));
else re=min(re, query2(mid+1,r,rson,p));
return re;
}
int main()
{
// setIO("input");
int n,i,j;
Init();
scanf("%s",str+1);
n=strlen(str+1);
for(i=1;i<=n;++i) extend(str[i]-'a',i);
for(i=1;i<=tot;++i) ++tax[t[i].len];
for(i=1;i<=tot;++i) tax[i]+=tax[i-1];
for(i=1;i<=tot;++i) rk[tax[t[i].len]--]=i;
build(1,n,1);
for(i=tot;i>1;--i)
{
int u=rk[i];
t[t[u].pre].cnt+=t[u].cnt;
t[t[u].pre].id=t[u].id;
if(t[u].cnt==1)
{
update(1,n,1,t[u].id-t[u].len+1,t[u].id-t[t[u].pre].len,t[u].id);
update2(1,n,1,t[u].id-t[t[u].pre].len,t[u].id,t[t[u].pre].len+1);
}
}
for(i=1;i<=n;++i) printf("%d\n",min(query(1,n,1,i)-i+1, query2(1,n,1,i)));
return 0;
}

  

bzoj 1396/2865: 识别子串 后缀自动机+线段树的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. BZOJ 1396||2865 识别子串

    这个不是题解,看不懂的,别看了 明明应该是会的,怎么还是写了6个小时呢... 把后缀数组.height数组.排名数组求出来,那么对于原串s的任意子串[x,y](表示第x个到第y个字符组成的子串,字符从 ...

  9. bzoj千题计划319:bzoj2865: 字符串识别(后缀自动机 + 线段树)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2865 同上一篇博客 就是卡卡空间,数组改成map #include<map> #inc ...

随机推荐

  1. 准备写个Golang开发的教程

    进入golang的开发已经差不多两年了,最近打算写个Golang的教程.目的是让有开发基础,没接触过Golang的人能够愉快高效地写出Golang项目. 1 记得17年底时候,有个特别小的项目,准备试 ...

  2. 第4章 JIT编译器

    4.1 JIT概览 语言根据执行的方式不同分为编译型语言和解释型语言.以C++为代表的编译型语言在执行前需要编译成机器码,不同的CPU需要不同的编译器,编译成功后在同一台机器不需再次编译.以Pytho ...

  3. c# 事件 +=和-=有什么区别

    +=就是發生新事件的同時通知你: -=就是發生新事件的同時不通知你:

  4. oracle 的分页、截断查询

    oracle 分页.截断查询 需求:从车管所的备案库中(oracle)取出数据,放到车综大数据平台(http方式) 现场情况:oracle中有三张表,CZRKXX(常住人口信息),ZDRYXX(重点人 ...

  5. 时间都去哪儿了?开源一个统计iPhone上App运行时间和打开次数的小工具【iOS8已失效】

    如今,大家每天都有大量时间花在手机上,但是,大家有没有想过自己的时间都花在哪些App上了呢?相信很多人都有这样的需求,不过iOS系统本身并不能显示每个App的运行时间和次数,因此,本人写了这样一个小工 ...

  6. SAP云平台上的ABAP编程环境里如何消费第三方服务

    在ABAP On-Premises环境下,使用ABAP编程消费第三方服务,相信很多ABAP顾问都已经非常熟悉了,无非就是使用CL_HTTP_CLIENT或者CL_REST_HTTP_CLIENT来发送 ...

  7. 打造完美Python环境(pyenv, virtualenv, pip)

    写在最前 在使用 Python 进行开发和部署的时候,经常会碰到Python版本或者依赖包或者对应版本不同导致各种意外情况发生. 本文将介绍如何通过 pyenv, virtualenv, pip三个工 ...

  8. Linux常用命令与详解

    在Linux系统中文件删除.创建.更改等操作都是通过一个个不同的命令来完成我们想要的操作,那么什么是命令呢? 凡是在字符操作界面中输入的能够完成特定操作和任务的字符串都可以称为命令.严格来说,命令通常 ...

  9. Kubernetes日志采集

    Kubernetes日志打印方式 标准输出 docker标准输出日志stdout和stderr,使用docker logs或者kubectl logs查看最新的日志(tail). 如果想看到更多的日志 ...

  10. Java8新特性之重复注解(repeating annotations)

    一.什么是重复注解 允许在同一申明类型(类,属性,或方法)的多次使用同一个注解 二.一个简单的例子java 8之前也有重复使用注解的解决方案,但可读性不是很好,比如下面的代码: 复制代码代码如下: p ...