123D
后缀数组+单调栈
看了好长时间,最后看了张神的程序才搞懂
意思就是求所有子串*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的更多相关文章
- Codeforces #123D: 后缀数组+单调栈
D. String You are given a string s. Each pair of numbers l and r that fulfill the condition 1 ≤ ...
- centos6环境下搭建irc服务器
问题描述 有时候逛技术社区,经常会发现有个叫IRC的东西存在,想搭建下看看到底是个什么东西 说明: 操作系统环境为CentOS6.5_64 安装irc服务器 通过yum进行安装,命令如下: yum i ...
- 迈出物联网的第一步,玩儿一下Arduino
大家知道,现在物联网Internet of Things(IoT) 方兴未艾,各种智能设备层出不穷,手表.手环.甚至运动鞋等可穿戴设备,还有智能家居产品,无时无刻不冲击着我们的思想和眼球.Autode ...
- Node.js入门笔记(4):文件系统(fs)
文件系统(FileSystem) 文件系统模块 对于文件无外乎创建修改添加. File System - 文件系统模块 - require('fs') fs模块是核心模块,需要使用require导入后 ...
- Autodesk的照片建模云服务—Autodesk ReCap 360 photo
现实捕捉技术方兴未艾,简单的讲现实捕捉技术就是把现实中的现状信息数字化到计算机中以便做进一步的处理.对于不同的应用目的会有不同的捕捉设备,工程或传媒娱乐行业中经常用到的肯定就是三维模型了.那如何得到三 ...
- 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 ...
- 3D建模与处理软件简介
[前言]自半年前笔者发表博客“什么是计算机图形学”以来,时常有人来向笔者询问3D模型的构建方法与工具.笔者的研究方向是以3D技术为主,具体包括3D建模,3D处理及3D打印三个方面,在3D建模与处理方面 ...
- 【Gerrit】Gerrit与Jenkins/Hudson CI服务器搭建
配置Git 很多系统(例如Linux)已经默认提供了Git,在Git主页也可以找到安装程序.对于Windows用户,最好的选择是MsysGit.请注意,如果你安装了Apple Developer To ...
- OSGEARTH三维地形开源项目
第一章 OSGEarth介绍 第二章 OSGEarth编译环境配置 OSGEarth的编译环境配置随着版本的不同.运行平台的不同,也有很大的差异.本章主要以Windows XP SP3(x86 ...
随机推荐
- XML——读与写
XML写入 private static void writeXml() { using (XmlTextWriter xml = new XmlTextWriter(@"C:\Users\ ...
- 调用.NET Serviced Component引发的性能问题及其解决
在企业用户环境里,.NET Serviced Component使用广泛.它比较好的把传统COM+封装和.NET应用逻辑衔接了起来,在服务器端应用起到重要作用..NET Serviced Compon ...
- iOS错误报告中关于崩溃地址的分析
http://blog.csdn.net/gaoyp/article/details/46912753 一.错误报告中的三种地址:stack addressload addresssymbol add ...
- switch方法中使用数字区间
function getCategory(age) { var category = ""; switch (true) { case isNaN(age): category = ...
- Oracle数据库的自动备份脚本
@echo off echo ================================================ echo Windows环境下Oracle数据库的自动备份脚本 echo ...
- Django settings.py的一些配置
官方文档:settings配置 静态文件配置链接 # 语言改为中文: LANGUAGE_CODE = "zh-hans" # 时区由UTC改为Asia/Shanghai,这样有关时 ...
- SSH免密登录的错误
为了避免每次在测试环境启动hadoop都需要输入密码, 使用免密操作 ssh-keygen,然后一直按enter键 接着需要输入root密码, 输入root密码后一直报错,密码不正确, permiss ...
- 51nod1103 N的倍数
[题解] 先预处理出模N意义下的前缀和sum[i]. 1.如果sum[i]=0,那么1~i的数之和就是N的倍数 2.sum[i]%N总共有0~N-1这N种情况:根据1,如果sum[i]为0则必定有解: ...
- Tensorflow读取csv文件(转)
常用的直接读取方法实例:#加载包 import tensorflow as tf import os #设置工作目录 os.chdir("你自己的目录") #查看目录 print( ...
- 【[Offer收割]编程练习赛13 B】最大子矩阵(自己的思路)
[题目链接]:http://hihocoder.com/contest/offers13/problem/2 [题意] [题解] 算出1..250*250这些数字每个数字的所有因子(成对的那种,即x* ...