题目分析:

求出height以后很明显跨越最小height的一定贡献是最小height,所以对于区间找出最小height再将区间对半分。

代码:

 #include<bits/stdc++.h>
using namespace std; const int maxn = ;
const int N = ; int n;
char str[maxn]; int sa[maxn],rk[maxn],X[maxn],Y[maxn];
int height[maxn],h[maxn],RMQ[maxn][],pos[maxn][]; int chk(int x,int k){
return rk[sa[x]]==rk[sa[x-]]&&rk[sa[x]+(<<k)]==rk[sa[x-]+(<<k)];
} void getsa(){
for(int i=;i<n;i++) X[str[i]]++;
for(int i=;i<=N;i++) X[i] += X[i-];
for(int i=n-;i>=;i--) sa[X[str[i]]--] = i;
for(int i = , num = ;i <= n;i++)
rk[sa[i]] = (str[sa[i]] == str[sa[i-]]?num:++num);
rk[sa[]] = ;
for(int k=;(<<k-)<=n;k++){
for(int i=;i<=N;i++) X[i] = ;
for(int i=n-(<<k-);i<n;i++) Y[i-n+(<<k-)+]=i;
for(int i=,j=(<<k-)+;i<=n;i++)
if(sa[i]>=(<<k-))Y[j++]=sa[i]-(<<k-);
for(int i=;i<n;i++) X[rk[i]]++;
for(int i=;i<=N;i++) X[i]+=X[i-];
for(int i=n;i>=;i--) sa[X[rk[Y[i]]]--] = Y[i];
int num = ; Y[sa[]] = ;
for(int i=;i<=n;i++) Y[sa[i]] = (chk(i,k-)?num:++num);
for(int i=;i<n;i++) rk[i] = Y[i];
if(num == n) break;
}
}
void getheight(){
for(int i=;i<n;i++){
if(i) h[i] = max(,h[i-]-); else h[i] = ;
if(rk[i] == ) continue;
int comp = sa[rk[i]-];
while(str[comp+h[i]] == str[i+h[i]])h[i]++;
}
for(int i=;i<n;i++) height[rk[i]] = h[i];
for(int i=;i<=n;i++) RMQ[i][] = height[i],pos[i][] = i;
for(int k=;(<<k)<=n;k++){
for(int i=;i<=n;i++){
if(i+(<<k-)>n) RMQ[i][k]=RMQ[i][k-],pos[i][k]=pos[i][k-];
else {
if(RMQ[i][k-]<RMQ[i+(<<k-)][k-]) pos[i][k] = pos[i][k-];
else pos[i][k] = pos[i+(<<k-)][k-];
RMQ[i][k] = min(RMQ[i][k-],RMQ[i+(<<k-)][k-]);
}
}
}
}
int getLCP(int L,int R){
if(L > R) swap(L,R);
if(L == R) return n-sa[L];
L++;
int k = ; while((<<k+)<=R-L+)k++;
if(RMQ[L][k]<RMQ[R-(<<k)+][k]) return pos[L][k];
else return pos[R-(<<k)+][k];
} long long ans = ; void divide(int l,int r){
if(l == r) return;
int ps = getLCP(l,r);
ans -= 2ll*(ps-l)*(r-ps+)*height[ps];
divide(l,ps-); divide(ps,r);
} void work(){
n = strlen(str);
getsa();
getheight();
for(int i=;i<=n;i++) ans += 1ll*i*i-i;
for(int i=;i<=n;i++) ans += 1ll*i*(n-i);
divide(,n);
printf("%lld\n",ans);
} int main(){
scanf("%s",str);
work();
return ;
}

AHOI2013 差异 【后缀数组】的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 这道题从大概半年以前就开始啃了,不过当时因为一些细节没调出来,看了Sakits神犇 ...

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

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

  9. BZOJ 3238: [Ahoi2013]差异 [后缀自动机]

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

  10. [Ahoi2013]差异(后缀自动机)

    /* 前面的那一坨是可以O1计算的 后面那个显然后缀数组单调栈比较好写??? 两个后缀的lcp长度相当于他们在后缀树上的lca的深度 那么我们就能够反向用后缀自动机构造出后缀树然后统计每个点作为lca ...

随机推荐

  1. Docker 最佳入门

    https://www.cnblogs.com/lanxiaoke/p/10432631.html https://www.cnblogs.com/viter/p/10463907.html http ...

  2. prime算法

    参考博客:https://blog.csdn.net/lqcsp/article/details/14118871 复杂度:O(n*n) #include <iostream> #incl ...

  3. Day2 Python基础之基本操作(一)

    1.常用命令 调用cmd窗口 Win+R cmd命令窗口清屏 cls cmd命令窗口在运行python时清屏 import os i=os.system('cls') cmd命令窗口在运行python ...

  4. 日志之环绕通知(AOP)

    环绕通知:一个完整的try...catch...finally结构 编写环绕通知方法,环绕通知需要携带ProceedingJoinPoint 这个类型的参数,ProceedingJoinPoint类型 ...

  5. js上传视频(jquery.form.js)

    // 上传目标触发点 <input type="file" class="upvideo" name="upvideo" id=&qu ...

  6. Laravel 服务容器、服务提供器、契约实例讲解

        前言 刚开始看laravel服务容器.契约.服务提供器的确生涩难懂,不单单是概念繁多,而且实际的demo很难找(找是找到了,但难用啊),最后就隔一段时间看一遍,大概个十来遍,还真给看出个门道, ...

  7. [FreeBuff]Trojan.Miner.gbq挖矿病毒分析报告

    Trojan.Miner.gbq挖矿病毒分析报告 https://www.freebuf.com/articles/network/196594.html 竟然还有端口转发... 这哥们.. 江民安全 ...

  8. JavaMail入门第一篇 邮件简介及API概述

    现如今,电子邮件在我们的生活当中扮演着越来越重要的角色,我们每个人几乎都会与其打交道(至少时不时我们都会接收到莫名其妙的垃圾邮件),在工作中,使用邮件进行交流沟通,可以使我们的工作有迹可循,也显的较为 ...

  9. day 7-13 数据库的数据类型

    一. 数据类型 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 注意:int类型的宽度是显示宽度,并非是数据的存储宽度 详细的介绍:http:// ...

  10. 使用 idea 产生错误The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized

    解决方法 spring.datasource.url=jdbc:mysql://localhost:3306/spring_cache?serverTimezone=GMT%2B8