后缀数组+单调栈

看了好长时间,最后看了张神的程序才搞懂

意思就是求所有子串*n*(n+1)/2 n是子串出现次数

事实上,lcp可以看成宽度为1,高度为lcp值的长方形,所有lcp放在一起就是一堆长方形放在一起,然后我们就要求对于每个高度对应的长方形的面积乘上一个值

每个长方形可以用单调栈求,也就是一个高度能最远延伸到哪里,单调栈维护当前长方形的高度递增。

比如说这个样子,

不满足单调性了,

这段红色的区间就要截掉

进来一个比较高的不用管

进来一个比较小的删掉红的

变成了这个样子

进来一个很小的

先把红色删掉

再把这块删掉,于是栈里又是不递增的了

最后我们把一个高度为0的lcp放入栈中,就把所有长方形加到答案里了。

还有一种情况,自己和自己也要加入答案,那么我们先把这个算掉再放入栈中。

做后缀数组要把所有和lcp无关的东西都砍掉,像自己和自己的答案应该单独统计,lcp有关的一起算,这样会方便很多

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 500010
ll ans;
int n,k, top;
char s[N];
int Rank[N],sa[N],temp[N],lcp[N],st[N][],l[N],r[N];
inline bool cp(int i,int j)
{
if(Rank[i]!=Rank[j]) return Rank[i]<Rank[j];
int ri=i+k<=n?Rank[i+k]:-;
int rj=j+k<=n?Rank[j+k]:-;
return ri<rj;
}
void Sa()
{
for(int i=;i<=n;++i)
{
Rank[i]=s[i]; sa[i]=i;
}
for(k=;k<=n;k<<=)
{
sort(sa+,sa+n+,cp);
temp[sa[]]=;
for(int i=;i<=n;++i) temp[sa[i]]=temp[sa[i-]]+(cp(sa[i-],sa[i]));
for(int i=;i<=n;++i) Rank[i]=temp[i];
}
}
void Lcp()
{
for(int i=;i<=n;++i) Rank[sa[i]]=i;
int h=;
for(int i=;i<=n;++i)
{
if(Rank[i]<=) continue;
int j=sa[Rank[i]-];
if(h>) --h;
for(;i+h<=n&&j+h<=n;++h) if(s[i+h]!=s[j+h]) break;
lcp[Rank[i]]=h;
}
}
ll mul(ll x)
{
return x * (x + 1ll) / 2ll;
}
int main()
{
scanf("%s",s+);
n = strlen(s + );
Sa();
Lcp();
for(int i = ; i <= n; ++i)
{
ans += (ll)(n - sa[i] + ) - max(lcp[i], lcp[i + ]);
int left = i;
while(top && lcp[i + ] < st[top][])
{
ans += mul(i - st[top][] + ) * (st[top][] - max(st[top - ][], lcp[i + ]));
left = st[top][];
--top;
}
++top;
st[top][] = left;
st[top][] = lcp[i + ];
}
printf("%lld\n", ans);
return ;
}

123D的更多相关文章

  1. Codeforces #123D: 后缀数组+单调栈

    D. String     You are given a string s. Each pair of numbers l and r that fulfill the condition 1 ≤  ...

  2. centos6环境下搭建irc服务器

    问题描述 有时候逛技术社区,经常会发现有个叫IRC的东西存在,想搭建下看看到底是个什么东西 说明: 操作系统环境为CentOS6.5_64 安装irc服务器 通过yum进行安装,命令如下: yum i ...

  3. 迈出物联网的第一步,玩儿一下Arduino

    大家知道,现在物联网Internet of Things(IoT) 方兴未艾,各种智能设备层出不穷,手表.手环.甚至运动鞋等可穿戴设备,还有智能家居产品,无时无刻不冲击着我们的思想和眼球.Autode ...

  4. Node.js入门笔记(4):文件系统(fs)

    文件系统(FileSystem) 文件系统模块 对于文件无外乎创建修改添加. File System - 文件系统模块 - require('fs') fs模块是核心模块,需要使用require导入后 ...

  5. Autodesk的照片建模云服务—Autodesk ReCap 360 photo

    现实捕捉技术方兴未艾,简单的讲现实捕捉技术就是把现实中的现状信息数字化到计算机中以便做进一步的处理.对于不同的应用目的会有不同的捕捉设备,工程或传媒娱乐行业中经常用到的肯定就是三维模型了.那如何得到三 ...

  6. The Basics of 3D Printing in 2015 - from someone with 16 WHOLE HOURS' experience

    全文转载自 Scott Hanselman的博文. I bought a 3D printer on Friday, specifically a Printrbot Simple Metal fro ...

  7. 3D建模与处理软件简介

    [前言]自半年前笔者发表博客“什么是计算机图形学”以来,时常有人来向笔者询问3D模型的构建方法与工具.笔者的研究方向是以3D技术为主,具体包括3D建模,3D处理及3D打印三个方面,在3D建模与处理方面 ...

  8. 【Gerrit】Gerrit与Jenkins/Hudson CI服务器搭建

    配置Git 很多系统(例如Linux)已经默认提供了Git,在Git主页也可以找到安装程序.对于Windows用户,最好的选择是MsysGit.请注意,如果你安装了Apple Developer To ...

  9. OSGEARTH三维地形开源项目

    第一章   OSGEarth介绍 第二章   OSGEarth编译环境配置 OSGEarth的编译环境配置随着版本的不同.运行平台的不同,也有很大的差异.本章主要以Windows XP SP3(x86 ...

随机推荐

  1. Python语言之变量1(数值,字符串,布尔)

    1.数值 整数:2, -2 长整数:2**1024, 2**2048(真的可以很~长~~~,手残算了个2**100000,IDLE还真给打出来了,ORZ) 浮点数:7.05, 1E2(100.0), ...

  2. 【sqli-labs】 less47 GET -Error based -String -Order By Clause(GET型基于错误的字符型Order By从句注入)

    http://192.168.136.128/sqli-labs-master/Less-47/?sort=1 改变sort的值,结果仍然是order by 1的结果 http://192.168.1 ...

  3. 取textaera里的值

    jQuery的.val()方法是专门用来获取表单元素值的,而textarea也属于表单元素所以可以直接用.val()方法获取. 不过要注意,由于textarea是个双标记因此.text()或.html ...

  4. Html5 WebSocket详细介绍

    什么是WebSocket?看过html5的同学都知道,WebSocket protocol 是HTML5一种新的协议.它是实现了浏览器与服务器全双工通信(full-duplex).HTML5定义了We ...

  5. 开发LED屏幕页面遇到的问题

    上上个礼拜公司的展销会活动需要一个展示在LED大屏幕的页面,顶部显示平台交易总金额,左右两边分别是厂家和买家实时交易记录,具体页面长下面这个样子 需求评审的时候产品说顶部的总金额要有一个数字滚动或者翻 ...

  6. 图的连通性问题之连通和最小环——Floyd算法

    Floyd 判断连通性 d[i][j]仅表示i,j之间是否联通 ;k<=n;k++) ;i<=n;i++) ;j<=n;j++) dis[i][j]=dis[i][j]||(dis[ ...

  7. (C/C++学习)7.数组及其访问方式

    说明:数组的数据类型是一种构造类型,而存储数组的内存是一段连续的存储区域.数组的数据类型决定了连续内存的访问方式,它包括数组的三要素:起始地址.步长以及元素个数. 一.一维数组 1.形式:type 数 ...

  8. 《零压力学Python》 之 第三章知识点归纳

    第三章(第一个程序)知识点归纳 编程犹如写剧本.Python函数与剧本差别不大,你可以反复调用函数,而它每次都执行预定的“脚本”(脚本也可以指整个程序). 在Python IDLE中,真正的编程是从编 ...

  9. i++与++i的区别及效率

    i++与++i的区别及效率   先看看基本区别:i++ :先在i所在的表达式中使用i的当前值,后让i加1++i :让i先加1,然后在i所在的表达式中使用i的新值 看一些视频教程里面写for循环的时候都 ...

  10. Java基础——基础数据类型与读入输出

    首先我们写完了HelloWorld就学会了java的一种输出 System.out.println() 用起来就像是被强化过的C++的puts函数 或者就是自带endl的cout函数,中间的" ...