BZOJ 3238 后缀数组+单调栈
单调栈跑两遍求出来 ht[i]为最小值的那段区间
//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=500050;
int n,cntA[N],cntB[N],A[N],B[N],sa[N],tsa[N],rk[N],ht[N],stka[N],stkb[N],top,l[N],r[N];
char s[N];
void SA(){
for(int i=1;i<=n;i++)cntA[s[i]]++;
for(int i=1;i<=256;i++)cntA[i]+=cntA[i-1];
for(int i=n;i;i--)sa[cntA[s[i]]--]=i;
rk[sa[1]]=1;
for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]);
for(int l=1;rk[sa[n]]<n;l<<=1){
memset(cntA,0,sizeof(cntA));
memset(cntB,0,sizeof(cntB));
for(int i=1;i<=n;i++)
cntA[A[i]=rk[i]]++,
cntB[B[i]=(i+l<=n?rk[i+l]:0)]++;
for(int i=1;i<=n;i++)cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1];
for(int i=n;i;i--)tsa[cntB[B[i]]--]=i;
for(int i=n;i;i--)sa[cntA[A[tsa[i]]]--]=tsa[i];
rk[sa[1]]=1;
for(int i=2;i<=n;i++)
rk[sa[i]]=rk[sa[i-1]]+(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]);
}
for(int i=1,j=0;i<=n;i++){
j=j?j-1:0;
while(s[i+j]==s[sa[rk[i]-1]+j])j++;
ht[rk[i]]=j;
}
}
int main(){
scanf("%s",s+1);
n=strlen(s+1),SA();
for(int i=1;i<=n;i++){
while(top&&stka[top]>ht[i])top--;
stka[++top]=ht[i],stkb[top]=i;
l[i]=stkb[top-1]+1;
}top=0;stkb[0]=n+1;
for(int i=n;i;i--){
while(top&&stka[top]>=ht[i])top--;
stka[++top]=ht[i],stkb[top]=i;
r[i]=stkb[top-1]-1;
}
long long ans=(long long)n*(n-1)*(n+1)>>1;
for(int i=2;i<=n;i++)
ans-=(long long)(i-l[i]+1)*(r[i]-i+1)*2*ht[i];
printf("%lld\n",ans);
}
BZOJ 3238 后缀数组+单调栈的更多相关文章
- BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)
BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...
- 【BZOJ-3238】差异 后缀数组 + 单调栈
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1561 Solved: 734[Submit][Status] ...
- BZOJ_3879_SvT_后缀数组+单调栈
BZOJ_3879_SvT_后缀数组+单调栈 Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个 ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...
- 【BZOJ3879】SvT 后缀数组+单调栈
[BZOJ3879]SvT Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干 ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
- BZOJ4199 [Noi2015]品酒大会 【后缀数组 + 单调栈 + ST表】
题目 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品 酒家"和"首席猎手"两个奖项,吸 ...
- [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】
题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...
- BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))
[传送门[(https://www.lydsy.com/JudgeOnline/problem.php?id=3238) 解题思路 首先原式可以把\(len\)那部分直接算出来,然后通过后缀数组求\( ...
随机推荐
- (整)deepin下mysql的安装与部分错误解决办法
deepin(深度)是国产Linux系统,程序员肯定要了解Linux系统啦,但是在程序安装上可能会有些不习惯,现在让我们来看看mysql在deepin上的安装过程. 1.傻瓜式命令行安装 这也是Lin ...
- 根据业务自己设计的.NET工厂模式架构
最近项目的架构需要做调整优化,根据业务需要写了一个简单的工厂模式架构 项目介绍:整个系统分为三大平台(这里用A,B,C来标示),每个平台又细分为多个APP客户端(每个APP都有appid来区分) 因为 ...
- Nginx下修改php.ini后重新加载配置文件命令
修改php.ini后 如,我的 php.ini 文件是放在 /etc/php.ini php 所在目录是 /www/Linux/php-5.2.17 修改 php.ini 后要用 php-fpm 来进 ...
- DP:***24种设计模式--转自刘伟
转自于高人的文章:http://blog.csdn.net/lovelion/article/details/17517213 2012年-2013年,Sunny在CSDN技术博客中陆续发表了100多 ...
- Windows各种计时器
(一):OnTimer类 1.打开对应对话框的类向导ClassWizard. 2.在消息映射MessageMaps中添加消息Message:WM_TIMER. 3.程序代码中将自动添加函数OnTime ...
- 关于maven-基本
笔记 Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object ...
- JavaScript Math 对象常用方法
Math.abs(x):可返回数的绝对值 Math.ceil(x):向上取整 Math.floor(x):向下取整 Math.max(x,y):最大值 Math.min(x,y):最小值 Math.r ...
- 搞不懂的算法-排序篇<2>
上一篇排序算法<1>中,排序算法的时间复杂度从N2到NlgN变化,但他们都有一个共同的特点,基于比较和交换数组中的元素来实现排序,我们称这些排序算法为比较排序算法.对于比较排序算法,所有的 ...
- Linux VFS分析(二)
inode的管理:Inode-cache hash表inode_hashtable索引节点缓存 dentry的管理: 我们知道,若干dentry描绘了一个树型的目录结构,这就是用户所看到的目录结构,每 ...
- vue常用方法
vue移动端ui库: http://mint-ui.github.io/#!/zh-cn vue做app开发使用: weex 官网地址:http://weex.apache.org/cn 1.Vue组 ...