BZOJ3238: [Ahoi2013]差异(后缀数组)
Description
.jpg)
Input
一行,一个字符串S
Output
一行,一个整数,表示所求值
Sample Input
Sample Output
解题思路:
看到lcp,想到了height数组,没错,这道题是一道后缀数组题。
前面那两项好像可以累和,值为(len-1)*len*(len+1)/2
就剩sigma(lcp)了。
想到了单调栈直接累和发现WA了,非常尴尬。
最后知道好像漏了点什么,就是说之前的height不可以说弹栈了就要遗弃,那是会漏解的。
要重复累加。也就是用dp数组来维护贡献,每次弹栈后累加。
你不会怕我加重吧,可以证明,弹栈只会在一个阶段停下,而之前的值在最终贡献中体现。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
int sa[];
int rnk[];
int has[];
int tmr[];
int hgt[];
char str[];
char ln[];
int stack[];
lnt dp[];
int top;
int len;
int cnt;
lnt ans;
bool Same(int a,int b,int l)
{
if(a+l>len||b+l>len)
return false;
return (rnk[a]==rnk[b])&&(rnk[a+l]==rnk[b+l]);
}
int main()
{
scanf("%s",str+);
len=strlen(str+);
for(int i=;i<=len;i++)
has[str[i]]++;
for(int i=;i<;i++)
if(has[i])
tmr[i]=++cnt;
for(int i=;i<;i++)
has[i]+=has[i-];
for(int i=;i<=len;i++)
{
sa[has[str[i]]--]=i;
rnk[i]=tmr[str[i]];
}
for(int k=;cnt!=len;k<<=)
{
cnt=;
for(int i=;i<=len;i++)
has[i]=;
for(int i=;i<=len;i++)
has[rnk[i]]++;
for(int i=;i<=len;i++)
has[i]+=has[i-];
for(int i=len;i;i--)
if(sa[i]>k)
tmr[sa[i]-k]=has[rnk[sa[i]-k]]--;
for(int i=;i<=k;i++)
tmr[len-i+]=has[rnk[len-i+]]--;
for(int i=;i<=len;i++)
sa[tmr[i]]=i;
for(int i=;i<=len;i++)
if(Same(sa[i],sa[i-],k))
tmr[sa[i]]=cnt;
else
tmr[sa[i]]=++cnt;
for(int i=;i<=len;i++)
rnk[i]=tmr[i];
}
hgt[]=;
for(int i=;i<=len;i++)
{
if(rnk[i]==)
continue;
int j=std::max(,hgt[rnk[i-]]-);
while(str[i+j-]==str[sa[rnk[i]-]+j-])
hgt[rnk[i]]=j++;
}
stack[]=;
for(int i=;i<=len;i++)
{
while(top&&hgt[stack[top]]>hgt[i])
top--;
dp[i]=(lnt)(i-stack[top])*(lnt)(hgt[i])+dp[stack[top]];
ans+=dp[i];
stack[++top]=i;
}
ans<<=;
printf("%lld\n",(lnt)(len-)*(lnt)(len+)*(lnt)(len)/-ans);
return ;
}
BZOJ3238: [Ahoi2013]差异(后缀数组)的更多相关文章
- bzoj3238 [Ahoi2013]差异 后缀数组+单调栈
[bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...
- [BZOJ3238][AHOI2013]差异(后缀数组)
求和式的前两项可以直接算,问题是对于每对i,j计算LCP. 一个比较显然的性质是,LCP(i,j)是h[rk[i]+1~rk[j]]中的最小值. 从h的每个元素角度考虑,就是对每个h计算有多少对i,j ...
- 【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈
[BZOJ3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...
- 【BZOJ-3238】差异 后缀数组 + 单调栈
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1561 Solved: 734[Submit][Status] ...
- bzoj 3238: [Ahoi2013]差异 -- 后缀数组
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- [AHOI2013] 差异 - 后缀数组,单调栈
[AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...
- BZOJ3238: [Ahoi2013]差异(后缀自动机)
题意 题目链接 Sol 前面的可以直接算 然后原串翻转过来,这时候变成了求任意两个前缀的最长公共后缀,显然这个值应该是\(len[lca]\),求出\(siz\)乱搞一下 #include<bi ...
- [bzoj3238][Ahoi2013]差异——后缀自动机
Brief Description Algorithm Design 下面给出后缀自动机的一个性质: 两个子串的最长公共后缀,位于这两个串对应的状态在parent树上的lca状态上.并且最长公共后缀的 ...
- BZOJ3238 [Ahoi2013]差异 【SAM or SA】
BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单 ...
随机推荐
- sublime配置python
Sublime Text 2作为一款轻量级的编辑器,特点鲜明.方便使用,愈发受到普罗大众的喜爱.我个人近期也開始用了起来.同一时候,我近段时间还在学习Python的相关东西.所以開始用ST2来写Pyt ...
- .Net 安装aliyun-oss
NuGet安装 如果您的Visual Studio没有安装NuGet,请先安装 NuGet. 安装好NuGet后,先在Visual Studio中新建或者打开已有的项目,然后选择工具 > NuG ...
- JS控制光标定位,定位到文本的某个位置
这是一个数字密码,要能够智能的跳转到文本的某个位置,就需要通过JS来控制跳转! 1.onkeyup监听 <input class="put" id="number- ...
- 13.ng-value
转自:https://www.cnblogs.com/best/tag/Angular/ 绑定给定的表达式到input[select]或 input[radio]的值上 <input type= ...
- 9.java 操作mongodb插入、读取、修改以及删除基础
1 package mongodb; import java.net.UnknownHostException; import java.util.ArrayList; import java.uti ...
- HDU 4372 Count the Buildings 组合数学
题意:有n个点上可能有楼房,从前面可以看到x栋楼,从后面可以看到y栋,问楼的位置有多少种可能. 印象中好像做过这个题,
- 洛谷——P2446 [SDOI2010]大陆争霸
https://www.luogu.org/problem/show?pid=2446#sub 题目背景 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的克里斯国.两个国家的人民分别 ...
- Apache Thrift使用总结
使用感受 之前对Thrift的理解有点不准确,使用之后发现Thrift比想象中的要简单得多. Thrift做的事情就是跨语言的分布式RPC,通过编写.thrift文件声明接口类和方法,client调用 ...
- java为什么要定义接口等相关解释
1.接口的作用是实现多重继承 因为只能继承一个类(规定的) 2.一个类只能继承一个父类,但是可以实现一个或多个接口 3.abstract关键词能让你在类里创建一个或多个没有定义的方法—你给出接口,但 ...
- Cisco PIX防火墙PPPoE拨号配置视频教学
Cisco PIX防火墙PPPoE拨号配置视频教学 本文出自 "李晨光原创技术博客" 博客,请务必保留此出处http://chenguang.blog.51cto.com/35 ...