BZOJ3238: [Ahoi2013]差异(后缀数组)
Description
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\)数组搞就好了,配合一下单 ...
随机推荐
- 我持续推动Rust语言支持Windows XP系统
前言 Rust好像长期以来不支持Windows XP系统.有不少用户发帖提议官方支持XP,基本上都被Rust官方开发人员明白的拒绝了.他们的对话大致上是以这种形式開始和结束的(当中乙方代表官方及其拥趸 ...
- android-继承BaseAdapter--自己定义适配器,getView运行多次的解决方法
定义的getView运行多次的ListView布局: <ListView android:id="@+id/lv_messages" android:layout_width ...
- android 视频开发2分之2(仿美拍,糗百)
上一篇写了分段录制和合并视频.这一篇则是选择视频,然后截断视频. 1.从sdcard中找到视频资源: 2.分析视频,拿到你须要的帧数当你的图片.(我的是依据參数来算的多少秒1帧的图片,通常是1秒1帧来 ...
- HDU 2444 The Accomodation of Students 二分图判定+最大匹配
题目来源:HDU 2444 The Accomodation of Students 题意:n个人能否够分成2组 每组的人不能相互认识 就是二分图判定 能够分成2组 每组选一个2个人认识能够去一个双人 ...
- DataTable转成Json
/// <summary> /// DataTable转成Json /// </summary> /// <param name=&quo ...
- windows常用命令有哪些(整理)
windows常用命令有哪些(整理) 一.总结 一句话总结:其实这个好学,只要先弄懂主干,清除主干,那么枝叶的添加逻辑就很清除了 这种多内容的,散乱的,弄清除主干效率就高了 1.windows命令行的 ...
- HDU 4372 Count the Buildings 组合数学
题意:有n个点上可能有楼房,从前面可以看到x栋楼,从后面可以看到y栋,问楼的位置有多少种可能. 印象中好像做过这个题,
- java 文件读写demo
分析错误日志: import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public ...
- HTTP 各种特性应用(一)
一. CORS 预请求 允许方法: GET. HEAD. POST 这三个方法 不需要预请求. 允许 Content-Type text/plain. multipart/form-data. app ...
- main函数argc,argv操作
使用main(int argc, char *argv[])==main(int argc, char **argv)的基本操作是linux编程的最基本的一步,在windows下也是exe脱离IDE运 ...