文章目录

  • 题目
  • 思路
  • 代码

题目

Luogu

n ≤ 2 ⋅ 1 0 5 n\le 2\cdot 10^5 n≤2⋅105

思路

性质: ∃ s i \exist\quad s_i ∃si​ 是 s i − 1 s_{i-1} si−1​ 的后缀
如图

那么此时可以缩短 s i − 1 s_{i-1} si−1​

然后联系后缀自动机不难想到是祖先关系

设 s i − 1 s_{i-1} si−1​ 代表结点为 u u u
设 s i s_{i} si​ 代表结点为 v v v
有 e n d p o s ( v ) ∈ e n d p o s ( u ) endpos(v)\in endpos(u) endpos(v)∈endpos(u)
由于是后缀,必定出现一次
现在还要找一次

如图,黑色的是 e n d p o s ( v ) endpos(v) endpos(v) 所有的是 e n d p o s ( u ) endpos(u) endpos(u)
那么任意找一个 x ∈ e n d p o s ( v ) x\in endpos(v) x∈endpos(v) 后找 [ x − m a x l e n v + m a x l e n u , x − 1 ] [x-maxlen_v+maxlen_u,x-1] [x−maxlenv​+maxlenu​,x−1] 中出现一个即可
线段树合并即可

代码

//#pragma GCC optimize(2)
#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<cstdio>
#include<queue>
#include<cmath>
#include<vector>
#include<cstring>
#include<climits>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define ULL unsigned long long
int read(){int f=1,x=0;char c=getchar();while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}return f*x;
}
#define MAXN 600000
#define INF 0x3f3f3f3f
int ed[MAXN+5];
int Root,scnt,lst,maxlen[MAXN+5],nxt[MAXN+5][27],fail[MAXN+5];
int Newnode(){int u=++scnt;fail[u]=0,maxlen[u]=0;memset(nxt[u],0,sizeof(nxt[u]));return u;
}
void Init(){scnt=0;Root=lst=Newnode();return ;
}
void Extend(int c,int id){int p=lst,cur=(lst=Newnode());ed[cur]=id;maxlen[cur]=maxlen[p]+1;while(p&&!nxt[p][c])nxt[p][c]=cur,p=fail[p];if(!p){fail[cur]=1;return ;}int q=nxt[p][c];if(maxlen[q]==maxlen[p]+1){fail[cur]=q;return ;}int clone=Newnode();ed[clone]=id;maxlen[clone]=maxlen[p]+1;memcpy(nxt[clone],nxt[q],sizeof(nxt[q]));fail[clone]=fail[q];fail[cur]=fail[q]=clone;while(p&&nxt[p][c]==q)nxt[p][c]=clone,p=fail[p];return ;
}
int ncnt,rt[MAXN+5],ch[25*MAXN+5][2];
void Insert(int &u,int L,int R,int p){u=++ncnt;if(L==R)return ;int Mid=(L+R)>>1;if(p<=Mid)Insert(ch[u][0],L,Mid,p);else Insert(ch[u][1],Mid+1,R,p);return ;
}
int Merge(int u,int v){if(!u||!v) return u|v;int p=++ncnt;ch[p][0]=Merge(ch[u][0],ch[v][0]);ch[p][1]=Merge(ch[u][1],ch[v][1]);return p;
}
int n;
vector<int> G[MAXN+5];
void DFS(int u){if(ed[u])Insert(rt[u],1,n,ed[u]);for(int i=0;i<(int)G[u].size();i++){int v=G[u][i];DFS(v);rt[u]=Merge(rt[u],rt[v]);}return ;
}
int ans,f[MAXN+5],fa[MAXN+5];
bool Query(int u,int L,int R,int qL,int qR){if(!u) return 0;if(qL<=L&&R<=qR)return 1;int Mid=(L+R)>>1;if(qL<=Mid)if(Query(ch[u][0],L,Mid,qL,qR))return 1;if(Mid+1<=qR)if(Query(ch[u][1],Mid+1,R,qL,qR))return 1;return 0;
}
void DP(int u){for(int i=0;i<(int)G[u].size();i++){int v=G[u][i];if(u==Root)f[v]=1,fa[v]=v;else{if(Query(rt[fa[u]],1,n,ed[v]-maxlen[v]+maxlen[fa[u]],ed[v]-1))f[v]=f[fa[u]]+1,fa[v]=v;else f[v]=f[fa[u]],fa[v]=fa[u];}ans=max(ans,f[v]);DP(v);}return ;
}
char S[MAXN+5];
int main(){n=read();scanf("%s",S+1);Init();for(int i=1;i<=n;i++)Extend(S[i]-'a'+1,i);for(int i=2;i<=scnt;i++)G[fail[i]].push_back(i);DFS(Root);DP(Root);printf("%d\n",ans);return 0;
}

Cool Slogans[CF700E][后缀自动机][Dp]相关推荐

  1. 【CF700E】Cool Slogans【后缀自动机】【可持久化线段树合并】【树上倍增】

    传送门 题意:给定字符串SSS,求一堆字符串s1,s2,s3,...,sks_1,s_2,s_3,...,s_ks1​,s2​,s3​,...,sk​,满足s1s_1s1​是SSS的子串,且sis_i ...

  2. hdu5343 后缀自动机+dp

    给定两个串,分别截取字串X和Y,连接组成X+Y,求不同的X+Y的方案数. 对于X+Y,如果重复的部分其实就是从同一个X+Y的某个地方断开弄成不同的X和Y,那么只要使得X和X+Y匹配得最长就行了. 因此 ...

  3. BZOJ2806(后缀自动机+DP)

    题目:http://61.187.179.132/JudgeOnline/problem.php?id=2806 题意:给定一个由M个01串组成的字典.依据这个字典和一个阀值L,可以断言一个01串是否 ...

  4. 洛谷P3975【天津省选2015】(后缀自动机DP)

    题目链接 https://www.luogu.com.cn/problem/P3975 题解 此题非常经典且重要,是sam的函谷关,必须拿下. 记录每个点endpos大小的方法是在parent树从下往 ...

  5. 后缀自动机+DP BZOJ 3238 差异

    分析: 其实题目就是要求任意两个后缀T[i]和T[j] (i< j) 的 LCP长度之和. 首先对输入的字符串反转后建立SAM. 令 一个节点的Max表示它代表的最长子串. 推论1: 原串中的两 ...

  6. BZOJ-3473 (广义后缀自动机:拓扑 or 启发式合并)

    BZOJ-3473 (广义后缀自动机:拓扑 or 启发式合并) 题目链接 题意 nnn个字符串,询问每个字符串一共有几个子串至少出现在nnn个字符串中的kkk个 思路: 拓扑 建广义后缀自动机, dp ...

  7. SPOJ 7258 (后缀自动机)

    转载:http://hzwer.com/4492.html 给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 搞出后缀自动机 dp处理出每个点往下走能 ...

  8. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

  9. BZOJ 4032 luogu P4112 [HEOI2015]最短不公共子串 (DP、后缀自动机)

    这其实是道水题... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4032 (luogu)https://www.luog ...

最新文章

  1. PAT(甲级)2019年冬季考试 7-4 Cartesian Tree
  2. crontab 总结
  3. 从Visual Studio里抓取抽象语法树(AST)
  4. 计算机作文1500字,写科技的作文1500字
  5. The Geometry has no Z values 解决办法(转载)
  6. 二叉树的几种递归和非递归式遍历:
  7. .net core HttpClient 使用之掉坑解析(一)
  8. Flask 蓝图,数据库链接
  9. 一个 Java 的 Socket 服务器和客户端通信的例子
  10. 详解Paint的setColorFilter(ColorFilter filter)
  11. ArcGIS API for Silverlight 调用GP服务绘制等值面
  12. ASP实现AJAX的几种方式!
  13. nuke软件功能有哪些?苹果Mac影视后期特效合成软件NUKE 13
  14. 用java写一个贪吃蛇小游戏(源码在最后)
  15. 防御 DDoS 的终极奥义——又拍云 SCDN
  16. linux安装微信 安装百度网盘 下载大文件
  17. 代理ip按功能分哪几类?
  18. centos安装uWSGI失败处理办法Exception: you need a C compiler to build uWSGI
  19. IETester汉化文件下载
  20. 世界互联网大会为什么把这么重要的奖颁给蚂蚁金服?

热门文章

  1. abiFilters
  2. vue中如何使用echarts——以折线图为例
  3. Windows Server 2012 R2 详细安装步骤
  4. web项目答辩总结_java web 答辩总结
  5. n级lfsr输出m序列c语言,第2章流密码(LFSR)
  6. C程序中的#line意义何在
  7. 【英语思维导图制作】万彩脑图大师教程 | 插入表情
  8. Kettle数据的导入导出—批量Excel表到数据库
  9. 福建省c语言等级考试成绩查询,福建省高校计算机等级考试成绩查询
  10. 【Leetcode】213. 打家劫舍II(House Robber II)