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\)数组搞就好了,配合一下单 ...
随机推荐
- HBase源代码分析之HRegion上MemStore的flsuh流程(二)
继上篇<HBase源代码分析之HRegion上MemStore的flsuh流程(一)>之后.我们继续分析下HRegion上MemStore flush的核心方法internalFlushc ...
- vue5 过滤器 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vim 插件之 surround.vim
surround.vim-这个插件主要是用来插入一些特殊符号的(成对出现) 下载地址 http://www.vim.org/scripts/script.php?script_id=1697 http ...
- .Net中字典的使用
/// <summary> /// 获取用户市信息 /// </summary> /// <param name="CustomerId">&l ...
- Ehcache整合spring配置,配置springMVC缓存
为了提高系统的运行效率,引入缓存机制,减少数据库访问和磁盘IO.下面说明一下ehcache和spring整合配置. 1. 需要的jar包 slf4j-api-1.6.1.jar ehcache-c ...
- Linux系统安全加固(一)
Linux系统安全加固(一) 去年8月,某所网站遭黑客攻击瘫痪虽然港交所随后及时启用备用系统,但还是致使7支股票1支债卷被迫停牌,次日再次遭受攻击而瘫痪:在去年年底继CSDN信息安全出现之后, ...
- C++ new 的用法
原文链接:http://www.builder.com.cn/2008/0104/696370.shtml “new”是C++的一个关键字,同时也是操作符.关于new的话题非常多,因为它确实比较复杂, ...
- NET 高效开发之不可错过的实用工具(第一的当然是ReSharper插件)
工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢?本文为 ASP.NET 开发者介绍一些高效实用的工具,包括 SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环节 ...
- tensorflow学习之路-----MNIST数据
''' 神经网络的过程:1.准备相应的数据库 2.定义输入成 3.定义输出层 4.定义隐藏层 5.训练(根据误差进行训练) 6.对结果进行精确度评估 ''' import tensorflow as ...
- 【TC SRM 718 DIV 2 B】Reconstruct Graph
[Link]: [Description] 给你两个括号序列; 让你把这两个括号序列合并起来 (得按顺序合并) 使得组成的新的序列为合法序列; 即每个括号都能匹配; 问有多少种合并的方法; [Solu ...