BZOJ 1396:识别子串 SA+树状数组+单调队列
1396: 识别子串
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 381 Solved: 243
[Submit][Status][Discuss]
Description

Input
Output
Sample Input
Sample Output
2
3
3
2
2
3
3
2
2
3
3
2
1
2
3
3
2
1
2
3
4
即j>=i+max{height[rank[i]],height[rank[i+1]]},令hi=i+max{height[rank[i]],height[rank[i+1]]}
②ansj=min(hi-i+1)i<=j,hi>=j;线段树维护[i,hi]的区间最值。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
const int len(100000),limt(255);
int str[len+10],sfa[len+10],rank[len+10],height[len+10];
int tmp[len+10],p[len+10],cnt[len+10];
int n,c[len+10],ans[len+10],q[len+10],li,hi;char ch[len+10];
struct data{int x,y;}h[len+10];
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
bool com(int x,int y,int l){return (rank[x]==rank[y])&&(rank[x+l]==rank[y+l]);}
void doubling()
{
for(int i=1;i<=n;i++){rank[i]=str[i];sfa[i]=i;}
for(int pos=0,l=0,sigma=limt;pos<n;sigma=pos)
{
pos=0;
for(int i=n-l+1;i<=n;i++)p[++pos]=i;
for(int i=1;i<=n;i++)if(sfa[i]>l)p[++pos]=sfa[i]-l;
memset(cnt,0,sizeof(int)*(sigma+1));pos=0;
for(int i=1;i<=n;i++)cnt[rank[i]]++;
for(int i=1;i<=sigma;i++)cnt[i]+=cnt[i-1];
for(int i=n;i>=1;i--)sfa[cnt[rank[p[i]]]--]=p[i];
for(int i=1;i<=n;i++)tmp[sfa[i]]=com(sfa[i],sfa[i-1],l)?pos:++pos;
for(int i=1;i<=n;i++)rank[i]=tmp[i];
l=!l?1:l<<1;
}
for(int i=1;i<=n;i++)rank[sfa[i]]=i;
for(int i=1,k,j;i<=n;i++)
{
k=sfa[rank[i]-1];
if(!k)continue;
j=height[rank[i-1]];
if(j)j--;
while(str[i+j]==str[k+j])j++;
height[rank[i]]=j;
}
}
int query(int x){int sum=0;for(;x;x-=x&(-x))sum=max(sum,c[x]);return sum;}
void put(int x,int y){for(;x<=n;x+=x&(-x))c[x]=max(c[x],y);}
int main()
{
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
scanf("%s",ch);n=strlen(ch);
for(int i=1;i<=n;i++)str[i]=ch[i-1]-'a'+1;
doubling();
for(int i=1;i<=n;i++)
{
h[i].x=i+max(height[rank[i]],height[rank[i]+1]);
h[i].y=i;
if(h[i].x>n+1)printf("NO");
}
for(int i=1,t;i<=n;i++)
{
if(h[i].x!=n+1)ans[h[i].y]=h[i].x-h[i].y+1;
else ans[h[i].y]=n;
t=query(h[i].y);
if(t)ans[h[i].y]=min(h[i].y-t+1,ans[h[i].y]);
if(h[i].x!=n+1)put(h[i].x,h[i].y);
}
q[li=1]=1;hi=1;
for(int i=2;i<=n;i++)
{
while(h[q[hi]].x<i&&hi<=li)hi++;
if(hi<=li&&h[q[hi]].x>=i&&h[q[hi]].x!=n+1)ans[h[i].y]=min(ans[h[i].y],h[q[hi]].x-h[q[hi]].y+1);
if(h[i].x!=n+1)
{
while(h[q[li]].x-h[q[li]].y>h[i].x-h[i].y&&li>=hi)li--;
q[++li]=i;
}
}
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
return 0;
}
BZOJ 1396:识别子串 SA+树状数组+单调队列的更多相关文章
- 大视野 1012: [JSOI2008]最大数maxnumber(线段树/ 树状数组/ 单调队列/ 单调栈/ rmq)
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 9851 Solved: 4318[Submi ...
- BZOJ.1396.识别子串(后缀自动机/后缀数组 线段树)
题目链接 SAM:能成为识别子串的只有那些|right|=1的节点代表的串. 设这个节点对应原串的右端点为r[i],则如果|right[i]|=1,即\(s[\ [r_i-len_i+1,r_i-le ...
- bzoj 1396 识别子串 后缀树+线段树
题目大意 给定一个长度\(\le100000\)的字符串 求每一个位置的最短识别子串 对于位置\(x\),能识别子串\(s[i...j]\)的条件是 1.\(i\le x \le j\) 2.\(s[ ...
- BZOJ 1396: 识别子串( 后缀数组 + 线段树 )
这道题各位大神好像都是用后缀自动机做的?.....蒟蒻就秀秀智商写一写后缀数组解法..... 求出Height数组后, 我们枚举每一位当做子串的开头. 如上图(x, y是height值), Heigh ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
- BZOJ 2743: [HEOI2012]采花 [树状数组 | 主席树]
题意: 查询区间中出现次数$>2$的颜色个数 一眼主席树,区间中$l \le last[i] \le r$的个数减去$l \le last[last[i]] \le r$的个数,搞两颗主席树来做 ...
- BZOJ.4826.[AHOI/HNOI2017]影魔(树状数组/莫队 单调栈)
BZOJ LOJ 洛谷 之前看\(mjt\)用莫队写了,以为是一种正解,码了3h结果在LOJ T了没A= = 心态爆炸(upd:发现是用C++11(NOI)交的,用C++11交就快一倍了...) 深刻 ...
随机推荐
- VNC协议分析
VNC协议分析 摘自: http://blog.csdn.net/forever_feng/article/details/4703088 简介 VNC(Virtual Network Computi ...
- Consuming JSON Strings in SQL Server
https://www.simple-talk.com/sql/t-sql-programming/consuming-json-strings-in-sql-server/ Consuming JS ...
- Unite 2017 | Unity引擎发展四大方向
Unite 2017 Shanghai已落幕,今天为大家分享本次大会备受关注的Keynote主题演讲.本次大会Keynote主题演讲聚焦了Unity全球领导团队,包括Unity创始人David Hel ...
- unity5.5打包
https://docs.unity3d.com/ScriptReference/BuildPipeline.BuildAssetBundles.html 5.34升5.5打包bundle遇到问题 A ...
- Visio画图(一):UML用例图
Visio画图(一):UML用例图 1.找到UML用例图 A.有网状态 第一步 在搜索框内输入用例图进行搜索. 第二步,移动鼠标直到找到用例图 B.无网状态 第一步 点击特别推荐旁的类别选项 第二步 ...
- Continuous Integration
https://dzone.com/articles/continuous-delivery-toolchain
- 条件分页 分页条件和页参数传递方式一 超链接拼串 方式二 使用查询表单searchForm
<%-- Created by IntelliJ IDEA. User: jie Date: 2019/5/10 Time: 20:00 To change this template use ...
- codeforces772C
给一段序列,给你去掉所有数字的顺序,输出每去掉一个数,当前联通的子序列的最大值. 倒着来,每次插入一个数,然后求联通的最大值,线段树每个节点标记一下,区间的左右是否插入了数字,还有如果有数字从左边/右 ...
- Hive_Hive的数据模型_分区表
Hive的数据模型之分区表 准备数据表: create table sampledata (sid int, sname string, gender string, language int, ma ...
- hibernate Restrictions用法 HibernateTemplate Hibernate结合spring
常用方法 http://www.jb51.net/article/41541.htm ........................................... 博客分类: Hiberna ...