Description

Input

一行,一个由小写字母组成的字符串S,长度不超过10^5

Output

L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长.

Sample Input

agoodcookcooksgoodfood

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

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N (200000+1000)
 5 using namespace std;
 6
 7 char s[N];
 8 int Ans,n;
 9
10 struct SGT
11 {
12     int Segt[N<<1];
13     SGT(){memset(Segt,0x7f,sizeof(Segt));}
14
15     void Update(int now,int l,int r,int l1,int r1,int k)
16     {
17         if (r<l1 || l>r1) return;
18         if (l1<=l && r<=r1){Segt[now]=min(Segt[now],k);return;}
19         int mid=(l+r)>>1;
20         Update(now<<1,l,mid,l1,r1,k); Update(now<<1|1,mid+1,r,l1,r1,k);
21     }
22     void Query(int now,int l,int r,int x)
23     {
24         Ans=min(Ans,Segt[now]);
25         if (l==r) return;
26         int mid=(l+r)>>1;
27         if (x<=mid) Query(now<<1,l,mid,x);
28         else Query(now<<1|1,mid+1,r,x);
29     }
30 }SGT[2];
31
32 struct SAM
33 {
34     int fa[N],son[N][28],right[N],step[N],End[N],od[N],wt[N];
35     int p,q,np,nq,last,cnt;
36     SAM(){last=++cnt;}
37
38     void Insert(int x,int pos)
39     {
40         p=last; last=np=++cnt; step[np]=step[p]+1; right[np]=1; End[np]=pos;
41         while (p && !son[p][x]) son[p][x]=np,p=fa[p];
42         if (!p) fa[np]=1;
43         else
44         {
45             q=son[p][x];
46             if (step[p]+1==step[q]) fa[np]=q;
47             else
48             {
49                 nq=++cnt; step[nq]=step[p]+1;
50                 memcpy(son[nq],son[q],sizeof(son[q]));
51                 fa[nq]=fa[q]; fa[q]=fa[np]=nq;
52                 while (son[p][x]==q) son[p][x]=nq,p=fa[p];
53             }
54         }
55     }
56     void Init()
57     {
58         int len=strlen(s+1);
59         for (int i=1; i<=cnt; ++i) wt[step[i]]++;
60         for (int i=1; i<=len; ++i) wt[i]+=wt[i-1];
61         for (int i=cnt; i>=1; --i) od[wt[step[i]]--]=i;
62         for (int i=cnt; i>=1; --i) right[fa[od[i]]]+=right[od[i]];
63     }
64     void Solve()
65     {
66         for (int i=1; i<=cnt; ++i)
67         if (right[i]==1)
68         {
69             SGT[0].Update(1,1,n,End[i]-step[i]+1,End[i]-step[fa[i]],End[i]+1);
70             SGT[1].Update(1,1,n,End[i]-step[fa[i]],End[i],step[fa[i]]+1);
71         }
72         for (int i=1; i<=n; ++i)
73         {
74             Ans=0x7fffffff;
75             SGT[0].Query(1,1,n,i); Ans-=i;
76             SGT[1].Query(1,1,n,i);
77             printf("%d\n",Ans);
78         }
79     }
80 }SAM;
81
82 int main()
83 {
84     scanf("%s",s+1);
85     n=strlen(s+1);
86     for (int i=1; i<=n; ++i)
87         SAM.Insert(s[i]-'a',i);
88     SAM.Init();
89     SAM.Solve();
90 }

转载于:https://www.cnblogs.com/refun/p/9370482.html

BZOJ1396:识别子串(SAM)相关推荐

  1. 【BZOJ-13962865】识别子串字符串识别 后缀自动机/后缀树组 + 线段树

    1396: 识别子串 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 312  Solved: 193 [Submit][Status][Discus ...

  2. BZOJ 1396:识别子串 SA+树状数组+单调队列

    1396: 识别子串 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 381  Solved: 243 [Submit][Status][Discus ...

  3. ●BZOJ 1396 识别子串

    题链: http://www.joyoi.cn/problem/tyvj-2301(非权限OI患者,苟且在joyoi...) 题解: 后缀自动机,线段树 先对原串建立后缀自动机,不难发现, 会影响答案 ...

  4. python 识别子串的位置_Python基础语法小白这一篇就足够了!

    一个多星期的 Python基础语法学习结束,整理了一些常用必备的知识要点笔记.大家可以参考参考,内容比较长,知识点涉及还是蛮全面的(没面向对象),面向对象总结了以后会再单独发一篇,没有耐心的朋友可以直 ...

  5. 暑假集训 ---- 字符串2 (SAM专题)

    P1368 工艺 把串插入 S A M SAM SAM 插两次,然后贪心找最小字典序即可 [AHOI2013]差异 两个串的最长公共后缀就是后缀自动机上 lca 的长度 于是把两个串反过来,对于每一个 ...

  6. 【BZOJ】4032: [HEOI2015]最短不公共子串(LibreOJ #2123)

    [题意]给两个小写字母串A,B,请你计算: (1) A的一个最短的子串,它不是B的子串 (2) A的一个最短的子串,它不是B的子序列 (3) A的一个最短的子序列,它不是B的子串 (4) A的一个最短 ...

  7. 通过解决“构造包含所有给定子串的最短字符串”问题思考算法优化

    最近由于工作相对比较忙,需要学习一些新的技术项目,写代码的时间比较少.继续解决百度2017秋招4星的题目,今天要分析的这个题目,是目前我遇到相对其他4星题目算是有一点难度的题目. 今天我们将从一个题目 ...

  8. [基于子串搜索的方法] BNDM算法

    BNDM算法的搜索方法与BDM算法相同,但它使用了位并行来识别子串. 与原始的BDM相比,BNDM更简单,内存用量更少,具有更好的引用局部性,并且易于扩展到更复杂的模式串的情形.   在当前搜索窗口内 ...

  9. python连接mysql用哪个模块_pymysql模块使用---Python连接MySQL数据库

    VS2010与水晶报表V13的打包集成小结 感谢孟子E章提供的技术咨询. 系统配置: Windows 7 + VS2010 , WinForm + DotNet4 + 水晶报表 这里说的打包集成,指的 ...

最新文章

  1. 常用的 css 样式 记录
  2. 如何对付费广告流量进行标记?
  3. python3 线程隔离_Python的线程隔离实现方法
  4. 怎样修改MFC中应用程序标题的图标?
  5. yarn : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本
  6. 软件设计师 - 数据流图
  7. 怎么用命令开远程主机的telnet服务 2
  8. iso8601 转换 java_java积累----ISO8601格式时间转化为Datetime类型
  9. 图片饱和度_做PPT时,文字放在图片上老是看不清,咋办?
  10. java arraylist
  11. MySQL数据库8(二十二)变量
  12. batch入门教程(4)
  13. Javascript的函数直接量定义
  14. 降维系列之 LTSA 局部切空间排列
  15. 【关于USB转485串口的一点认识/疑问】
  16. WAITED TOO LONG FOR A ROW CACHE ENQUEUE LOCK!
  17. powerbuilder建数据库
  18. 模型评估与改进(三)// 评估指标
  19. 数据中台 第8章 数据资产管理
  20. “低代码”革了谁的命?

热门文章

  1. 深度学习中的验证集和超参数简介
  2. OpenCV中resize函数五种插值算法的实现过程
  3. 【Qt】QWidget对样式表设置边框无效的解决方法
  4. 启动子级时出错_减速机安装与使用时需注意的八个要点,细节很重要!
  5. python加载图片的方法_python从网络读取图片并直接进行处理的方法
  6. html文字中横线_谈PPT课件中自定义动画应用之内容控制
  7. Java项目:OA办公自动化系统设计和实现(java+springboot+freemarker+mysql+maven+mybatis+jpa)
  8. mimo系统matlab,OFDM—MIMO系统的matlab程序
  9. springboot 订单重复提交_Spring Boot (一) 校验表单重复提交
  10. python类和对象课件_简单解释Python的类和对象