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 ...
随机推荐
- strut2 拦截器 使用
拦截器是strut2里一个很振奋人心的应用.通过配置拦截器可以在action执行之前进行一些初始化或者是其他的操作,但是在action执行之后,返回结果就已经确定,结果是很难改变了(目前我还不知道怎么 ...
- Postfix 故障记录
1.postfix 目录/var/mail/USER文件大小限制报错 解决方式: 编辑 /etc/postfix/main.cf 文件添加以下内容 mailbox_size_limit = 51200 ...
- HDU_3308_线段树_区间合并
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- Git学习总结三(工作区和暂存区、撤销修改)
工作区和暂存区 工作区(Working Directory) 就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区: 版本库(Repository) 工作区有一个隐藏目录.git, ...
- Python学习笔记——Matplot库
https://www.cnblogs.com/laoniubile/p/5893286.html 一.基本指令 import matplotlib.pyplot as plt plt.figure ...
- python之urllib库
urllib库 urllib库是Python中一个最基本的网络请求库.可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据. urlopen函数: 在Python3的urlli ...
- golang实现高阶函数之filter
package main import "fmt" type student struct{ name string grade int8 } func filter(stu [] ...
- js用正则表达式将英文引号字符替换为中文引号字符
<script> $(function(){ var str='"我是英文版的引号",我要变成"中文版的引号"'; alert(replaceDqm ...
- 第六节:web爬虫之urllib(二)
二.urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, metho ...
- Java基础学习总结(69)——匿名内部类与Lambda表达式
前言 Java Labmda表达式的一个重要用法是简化某些匿名内部类(Anonymous Classes)的写法.实际上Lambda表达式并不仅仅是匿名内部类的语法糖,JVM内部是通过invokedy ...