#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
typedef long long ll;
char s[MAXN];
int n,siz[MAXN<<1];
ll ans=0;
const int inf=1e8;
struct SuffixTree{
int link[MAXN<<1],len[MAXN<<1],start[MAXN<<1],s[MAXN<<1];
int n,tail,now,rem,ch[MAXN<<1][27];
SuffixTree(){tail=1,n=0,rem=0,now=1,len[0]=inf;}
int newnode(int st,int le){
link[++tail]=1;start[tail]=st;len[tail]=le;return tail;
/*build new node
link->1,start=st(have been known)
len->le have been known
tail is the new number*/
}
void Extend(int x){
s[++n]=x;rem++;
/*add len(n),add rem
n->all strings' number
rem->now length(not the waited suffixstrings
suffixstrings is showed by "rem" & "now"
start[u]&len[u]:
is meaning of u's father is s[start[u]->start[u]+len[u]-1]*/
for(int last=1;rem;){
while(rem>len[ch[now][s[n-rem+1]]])
rem-=len[now=ch[now][s[n-rem+1]]];
/*
find the edge which the head is s[n-rem+1]
because that len(rem) may bigger than this edge's len
so we should del it's len and jump to the next
this is the setp2.
*/
int &v=ch[now][s[n-rem+1]];int c=s[start[v]+rem-1];
/*
v->the edge's last point
c->this edge's last character
*/
if(!v||x==c){
link[last]=now;last=now;
if(!v)v=newnode(n,inf);
/*
if there is no edge which is follow the rule
or,2 step is failed
then we should add the "suffix link"->link[last]=now,last=now
*/
else break;
/* if we find this edge is being,also
the last character have been there
it's meaning that we needn't to add now's character
so,we should break.
*/
}
else{
// if the last character is not being
int u=newnode(start[v],rem-1);
// build a new node,and split this edge
ch[u][c]=v;ch[u][x]=newnode(n,inf);
/*
u->have two points:one is v->inherit the before
and the other one is x:insert x.
*/
start[v]+=rem-1;len[v]-=rem-1;
/*
also,because we split this road
v's start and len should be updated
start+=rem-1,also the len[v] should cut rem-1
*/
link[last]=v=u;last=u;
//build lead to update the suffix link.
}
if(now==1)rem--;
/*
root is 1
if now=1,rem should be less
*/
else now=link[now];
/*
else,in order to add the next character,we should jump to the now's suffix link.
the meaning of suffix link is making find the next right edge and updating it more convenient and faster.
*/
}
}
}sft;
int dfs(int u,int dep){
if(dep>=inf)return 1;
siz[u]=0;
for(int i=0;i<=26;++i){
if(sft.ch[u][i]){
/*
if we can jump this edge
then,we continue to dfs and update the siz
*/
int d=dfs(sft.ch[u][i],dep+sft.len[sft.ch[u][i]]);
siz[u]+=d;
}
}
if(siz[u]>=2)ans=max(ans,1LL*siz[u]*dep);//the problem's querying
return siz[u];
}
int main(){
scanf("%s",s+1);
int n=strlen(s+1);
for(int i=1;i<=n;++i)s[i]-='a',sft.Extend(s[i]);//Extend the string
sft.Extend(26);//End character
dfs(1,0);//add up the answer
printf("%lld\n",ans);
}

\(\text{The code has explained by English.And the explaining will be updated after the High school entrance examination}\)

【暂咕咕咕】SuffixTree的更多相关文章

  1. (转)S5pv210 HDMI 接口在 Linux 3.0.8 驱动框架解析 (By liukun321 咕唧咕唧)

    作者:liukun321 咕唧咕唧 日期:2014.1.18 转载请标明作者.出处:http://blog.csdn.net/liukun321/article/details/18452663 本文 ...

  2. u-boot for tiny210 ver1.0(by liukun321咕唧咕唧)

     新版本下载: 下面的链接提供了较新版本的源码 ver4.0源码下载:u-boot for tiny210 ver4.0 ver3.1源码下载: u-boot for tiny210 ver3.1 v ...

  3. 基于S5pv210流媒体server的实现之网络摄像头(by liukun321 咕唧咕唧)

    这里仅介绍流媒体server端的实现思路.及编码注意问题,不会贴代码的详细实现. 直接入正题先介绍一下系统硬件框架: server端连接PC机用VLC播放例如以下图: server端应用程序能够分为图 ...

  4. linux多线程驱动中调用udelay()对整个系统造成的影响(by liukun321咕唧咕唧)

    以前没考虑过这个问题,而且之前可能运气比较好,虽然用了udelay但也没出什么奇怪的问题,今天在 CSDN上看到了一篇关于此问题帖子,觉得很受用,再此做简要的记录和分析: 驱动开的是内核线程 跟普通进 ...

  5. FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析&移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)

    这是几个月以前的东西了,在彻底遗忘之前拿出来好好写写.做个笔记,也算是造福后来人了.在做这个项目之前,没有做过电容屏的驱动,印象中的电容触摸屏是不需要校正的.IC支持多大的屏就要配多大的屏.但是拿到需 ...

  6. S5pv210 HDMI 接口在 Linux 3.0.8 驱动框架解析

    作者:liukun321 咕唧咕唧 日期:2014.1.18 转载请标明作者.出处:http://blog.csdn.net/liukun321/article/details/18452663 本文 ...

  7. 聊聊GIS中的坐标系|再版

    本文约6500字,建议阅读时间15分钟. 作者:博客园/B站/知乎/csdn/小专栏 @秋意正寒 版权:转载请告知,并在转载文上附上转载声明与原文链接(https://www.cnblogs.com/ ...

  8. [zt]给你的Mp4大换血,精选Touch里3年收集的900多首歌,"经典不忍去的""最新近流行的",与你共享~~

    如果你是音乐爱好者: 这些歌, 请戴上耳机, 调大音量, 一个人听 ,全世界 都是你的!!!!! (一)这些歌很温暖,没有金属味,适合有阳光的午后,很悠闲... [Anaesthesia]Maximi ...

  9. 关于Yaffs2在u-boot中的支持

    开发板是一块2G的MLC的NandFlash,页大小8k+512,为其移植u-boot到yaffs2这了.以前在Mini2440上移植过2k+64的slc的NandFlash的Yaffs2支持,当然也 ...

随机推荐

  1. Python自动化测试入门科技树

    Python基础: 入门语法和数据类型: 编码环境安装基本语法 常用数据类型 常用运算符 Llist.Tuple.Dict.if&for.while Python进阶: 函数: 语法 内置函数 ...

  2. Codeforces1247D Power Products 暴力+优化

    题意 给定数组\(a(\left| a \right|\leq 10^5)\)和整数\(k(2\leq k \leq 100)\),问满足一下条件的二元组\(<i,j>\)的数目: \(1 ...

  3. Java垃圾回收略略观

    本文主要介绍Java垃圾回收(Garbage Collection),90%干货,文字颇多,需要耐心一点看. [对象判断状态算法] ------引用计数法 在创建对象时,为对象创建一个伴生的引用计数器 ...

  4. 干货:用好这13款VSCode插件,工作效率提升10倍

    文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 大家好我是lemon, 马上进入我们今天的主题吧. 又 ...

  5. C007:输入美元数量,用最少的20美元,10美元,5美元和1美元付款

    代码: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int amount; do{ printf(&quo ...

  6. [bash]调用linux命令获得结果存入变量的两种方式

    代码: #!/bin/bash ls=$(ls) echo $ls whoami=`whoami` echo $whoami 执行结果: [os-××××××××101z ~]$ sh cmd2.sh ...

  7. 深入理解Java中的装箱与拆箱

    一.Java数据类型 1.在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是: 整数型:byte̵,short̵,int̵,l ...

  8. Httprunner框架学习

    前言 HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试. 官方文档:https://docs.httprunner. ...

  9. Java面试炼金系列 (1) | 关于String类的常见面试题剖析

    Java面试炼金系列 (1) | 关于String类的常见面试题剖析 文章以及源代码已被收录到:https://github.com/mio4/Java-Gold 0x0 基础知识 1. '==' 运 ...

  10. [LeetCode] 17. 电话号码的字母组合(回溯)

    题目 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 1 不对应任何字母. 示例: 输入:"23" 输出:[& ...