题目分析:

求出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. netty同端口监听tcp和websocket协议

    前言: 软件通信七层结构(osi模型)中由协议套协议最终组成最高级应用层协议(http等等),下三层结构偏向与数据通信,上三层更偏向于数据处理,中间的传输层则是连接上三层与下三层之间的桥梁,每一层都做 ...

  2. elasticsearch开启外网访问

    默认情况下,Elastic 只允许本机访问,如果需要远程访问,可以修改 Elastic 安装目录的config/elasticsearch.yml文件,去掉network.host的注释,将它的值改成 ...

  3. Golang-教程

    http://www.runoob.com/go/go-environment.html https://www.pythonav.cn/

  4. java 浅克隆 深克隆

    对象的克隆是java的一项高级技术,他可以根据给定的对象,获得与其完全相同的另一个对象. 1.浅克隆主要是复制对象的值 2.深克隆:当类存在聚合关系的时候,克隆就必须考虑聚合对象的克隆,可以复制引用类 ...

  5. servlet总结:Servlet基础

    Servlet基础 1.手工编写第一个Servlet ⑴继承HttpServlet ⑵重写doGet()或者doPost()方法 ⑶在web.xml中注册Servlet 2.使用eclipse编写第一 ...

  6. MapReduce过程<原创>

    一.预处理阶段 二.Map阶段 一个Map任务被JobTracker(管家)分配到多个TaskTracker(弟弟)执行,如下图所示,弟弟的map()只负责拆分,虽然map()输出两个相同的键值对,但 ...

  7. 简单封装mongodb

    首先安装mongodb  npm i mongodb --save 简单封装,在modules目录下新建db.js var MongoClient=require('mongodb').MongoCl ...

  8. redux模块化demo

    store.js 在redux中 store 是唯一的. import {createStore} from 'redux'; import reducer from './reducer' // 引 ...

  9. Azure系列2.1 —— com.microsoft.azure.storage.blob

    网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习心得做下笔记,文中不正确地方请大家指正. Azure Blob ...

  10. [转帖]Docker的数据管理(volume/bind mount/tmpfs)

    Docker(十五)-Docker的数据管理(volume/bind mount/tmpfs) https://www.cnblogs.com/zhuochong/p/10069719.html do ...