Description

Input

一行,一个字符串S

Output

一行,一个整数,表示所求值

Sample Input

cacao

Sample Output

54

解题思路:

看到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]差异(后缀数组)的更多相关文章

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

    [bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  2. [BZOJ3238][AHOI2013]差异(后缀数组)

    求和式的前两项可以直接算,问题是对于每对i,j计算LCP. 一个比较显然的性质是,LCP(i,j)是h[rk[i]+1~rk[j]]中的最小值. 从h的每个元素角度考虑,就是对每个h计算有多少对i,j ...

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

    [BZOJ3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  4. 【BZOJ-3238】差异 后缀数组 + 单调栈

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1561  Solved: 734[Submit][Status] ...

  5. bzoj 3238: [Ahoi2013]差异 -- 后缀数组

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...

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

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

  7. [AHOI2013] 差异 - 后缀数组,单调栈

    [AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...

  8. BZOJ3238: [Ahoi2013]差异(后缀自动机)

    题意 题目链接 Sol 前面的可以直接算 然后原串翻转过来,这时候变成了求任意两个前缀的最长公共后缀,显然这个值应该是\(len[lca]\),求出\(siz\)乱搞一下 #include<bi ...

  9. [bzoj3238][Ahoi2013]差异——后缀自动机

    Brief Description Algorithm Design 下面给出后缀自动机的一个性质: 两个子串的最长公共后缀,位于这两个串对应的状态在parent树上的lca状态上.并且最长公共后缀的 ...

  10. BZOJ3238 [Ahoi2013]差异 【SAM or SA】

    BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单 ...

随机推荐

  1. Haproxy压测

    目的:测试Haproxy压测情况 环境: Ha服务器:8核16G虚机,后端6个2核4G,压测客户端3个2核4G 安装和优化: 一.Haproxy #cd /opt/soft #wget http:// ...

  2. Redis封装之String

    RedisBase类 /// <summary> /// RedisBase类,是redis操作的基类,继承自IDisposable接口,主要用于释放内存 /// </summary ...

  3. @Transactional 事务注解

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = ...

  4. 手动新建hive编程环境(以hive-1.0.0和hive-1.2.1为例)

    如下,是用maven构建项目,本篇博文重点不是这个.初学者(小白)变成小鸟后,建议开始用maven啦! Eclipse下Maven新建项目.自动打依赖jar包(包含普通项目和Web项目) HBase ...

  5. How Javascript works (Javascript工作原理) (十三) CSS 和 JS 动画底层原理及如何优化其性能

    个人总结:读完这篇文章需要20分钟. 这是 JavaScript 工作原理的第十三章. 概述 正如你所知,动画在创建令人叹服的网络应用中扮演着一个关键角色.由于用户越来越注重用户体验,商户开始意识到完 ...

  6. angular实现简单的pagination分页组件

    不想使用第三方库,只想使用一个分页器,那么就简单的实现一个,效果如下: 1.使用方式: <custom-pagination *ngIf="enterpriseList.length& ...

  7. JS数组去重的6种算法实现

    1.遍历数组法 最简单的去重方法,实现思路:新建一新数组,遍历传入数组,值不在新数组就加入该新数组中:注意点:判断值是否在数组的方法"indexOf"是ECMAScript5 方法 ...

  8. 【Henu ACM Round #13 C】 Ebony and Ivory

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先求出c-bx的所有可能 ->存在map里面 然后枚举y看看ay在不在map里面 在的话就有解. 这样复杂度是\(O(N*lo ...

  9. android側滑菜单-DrawerLayout的基本使用

    眼下主流App开发中,部分是以側滑菜单为主布局架构,曾经做android側滑菜单时.大多选择使用github上的第三方开源框架SildingMenu,可是这个框架还是稍显笨重.好消息是google已经 ...

  10. uva103 - Stacking Boxes(DAG)

    题目:uva103 - Stacking Boxes(DAG) 题目大意:给出N个boxes, 而且给出这些箱子的维度.要求找一个最长的序列.可以使得以下的箱子一定可以有个维度序列大于上面的那个箱子的 ...