Time:2016.05.23
Author:xiaoyimi
转载注明出处谢谢


传送门
思路:
题意已经说的很明白了。
关键在于如何快速求得各lcp的和
有一个重要的性质

排名为i和j(i<j)的最长前缀长度=min(height[i+1..j])

对于排名为i的后缀,想要求得f[i]=∑lcp(i,j)f[i]=∑lcp(i,j)(i<j)我们只用维护好(i,j]区间的height最小值就好,而且如果遇到某个j,height[j]比height[i]小,那么j及其后的后缀对答案的贡献就是f[j]了,j之前的后缀一共是j-i个,对答案的贡献就是height[i]*(j-i);反之如果height[j]>=height[i],那么height[j]以后对答案没有任何贡献(因为有比它小的height[i]存在),直接排除它,也就是说对于height的使用是存在单调性的,使用单调栈就好(一开始我还不怎么会单调栈,蛋疼了好久)
注意:
1.起初对栈底放入len+1,使得栈不为空,从而计算各个值
2.对于原式中lcp以外的东西,我们可以把它化成(n是字符串长度)
(n(n+1)(2n+1)6−n(n+1)2)∗32(\frac{n(n+1)(2n+1)}6-\frac{n(n+1)}2)*\frac32
代码:

#include<bits/stdc++.h>
#define M 500004
#define LL long long
using namespace std;
char s[M];
int w[M],cnt[M],sa[M],rank[M],tmp[M],id[M],height[M];
LL ans,f[M];
stack<int>S;
void SA(int len,int up)
{int *rk=rank,p=0,*t=tmp,d=1;for (int i=0;i<len;i++) cnt[rk[i]=w[i]]++;for (int i=1;i<up;i++) cnt[i]+=cnt[i-1];for (int i=len-1;i>=0;i--) sa[--cnt[rk[i]]]=i;for (;;){for (int i=len-d;i<len;i++) id[p++]=i;for (int i=0;i<len;i++)if (sa[i]>=d) id[p++]=sa[i]-d;for (int i=0;i<up;i++) cnt[i]=0;for (int i=0;i<len;i++) cnt[t[i]=rk[id[i]]]++;for (int i=1;i<up;i++) cnt[i]+=cnt[i-1];for (int i=len-1;i>=0;i--) sa[--cnt[t[i]]]=id[i];swap(t,rk);p=1;rk[sa[0]]=0;for (int i=0;i<len-1;i++)if (sa[i]+d<len&&sa[i+1]+d<len&&t[sa[i]]==t[sa[i+1]]&&t[sa[i]+d]==t[sa[i+1]+d])rk[sa[i+1]]=p-1;elserk[sa[i+1]]=p++;if (p==len) break;d<<=1;up=p;p=0;}
}
void Height(int len)
{for (int i=1;i<=len;i++) rank[sa[i]]=i;int k=0,x;for (int i=0;i<len;i++){k=max(k-1,0);x=sa[rank[i]-1];while (w[i+k]==w[x+k]) k++;height[rank[i]]=k;}
}
main()
{scanf("%s",s);int len=strlen(s);ans=((LL)len*(len+1)*(len*2+1)/6-(LL)len*(len+1)/2)*3/2;for (int i=0;i<len;i++) w[i]=s[i]-'a'+1;SA(len+1,28);Height(len);S.push(len+1);for (int i=len;i>=1;i--){while(height[S.top()]>height[i]) S.pop();f[i]=(LL)height[i]*(S.top()-i)+f[S.top()];ans-=f[i]<<1;S.push(i);}printf("%lld",ans);
}

【BZOJ3238】差异,后缀数组+单调栈维护height相关推荐

  1. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]

    题目地址 - GO-> 题目大意: 给定一个长度为 nn 的字符串SS,令TiTi表示它从第ii个字符开始的后缀,求以下这个式子的值: ∑1≤i<j≤nlen(Ti)+len(Tj)−2× ...

  2. 【BZOJ3879】SvT,后缀数组+单调栈维护sum

    Time:2016.08.15 Author:xiaoyimi 转载注明出处谢谢 如果有不明白的地方可以在下面评论问我 传送门 思路: 建立后缀数组求出Height 如果说对每次询问暴力求LCP累加的 ...

  3. [Ahoi2013]差异[后缀数组+单调栈]

    链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...

  4. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2326  Solved: 1054 [Submit][Stat ...

  5. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  6. POJ - 3415 Common Substrings(后缀数组+单调栈)

    题目链接:点击查看 题目大意:给出两个字符串,再给出一个k,问两个字符串中长度大于等于k的公共子串有多少个(种类可重复) 题目分析:因为涉及到了子串问题,先用后缀数组跑出height数组来,接下来如果 ...

  7. [bzoj3238]差异(后缀数组+单调栈)

    显然我们可以先把len(Ti)+len(Tj)的值先算出来,再把LCP减去.所有len(Ti)+len(Tj)的值为n*(n-1)*(n+1)/2,这个随便在纸上画一画就可以算出来的. 接下来问题就是 ...

  8. bzoj 3238: [Ahoi2013]差异(后缀数组+单调栈)

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 3443  Solved: 1562 [Submit][Stat ...

  9. BZOJ3879: SvT【后缀数组+单调栈】

    Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...

最新文章

  1. [译] 写给前端开发者的 GraphQL 指南
  2. 漫谈可视化Prefuse(四)---被玩坏的Prefuse API
  3. G - 数据结构实验之查找七:线性之哈希表
  4. m6000路由器产品介绍与基本操作_交换机与路由器的区别及光模块搭配方案_光模块吧...
  5. python 代码片段6
  6. 动动嘴皮子就解决身份安全验证问题,这很NICE
  7. java天气app_MVP+RxJava2+Retrofit2 实况天气app
  8. 在cmd命令行下编译运行C/C++源文件
  9. 性质极其恶劣!针对基因编辑婴儿,怀进鹏这样说…
  10. python基本命令range_Python的Range()函数(指南)
  11. pandas学习笔记三之处理丢失数据
  12. iOS中 语音识别功能/语音转文字教程具体解释 韩俊强的博客
  13. 剖析Elasticsearch集群系列之二:分布式的三个C、translog和Lucene段
  14. Burp新手抓包教程(HTTPS抓包)
  15. 制作HTML邮件邮箱注意问题和解决方案--兼容手机邮箱、电脑邮箱和邮件客户端
  16. flask框架可以做什么?
  17. 深度学习中关于 “深度” 的理解
  18. 什么是CDN加速服务器?
  19. spring加载流程之AnnotatedBeanDefinitionReader
  20. Qt与Mysql进行连接实现账号的注册登录和密码修改和验证码

热门文章

  1. 物联网与人工智能之间的区别与联系
  2. 【带着canvas去流浪(11)】Three.js入门学习笔记
  3. 【Python3网络爬虫开发实战】1.3.3-pyquery的安装
  4. Kotlin学习笔记 第二章 类与对象 第七节 数据类
  5. 设计模式笔记十九:备忘录模式
  6. Android笔记 simpleAdapter demo
  7. 素数的有关性质(二)欧拉函数的一些定理证明与计算
  8. 【图像处理基础知识】python+opencv显示中文
  9. Zookeeper启动闪退可能原因及解决方案
  10. Mobaxterm中使用git log报错/bin/busybox.exe less -R no such file or directory