【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈
【BZOJ3238】[Ahoi2013]差异
Description
Input
一行,一个字符串S
Output
一行,一个整数,表示所求值
Sample Input
Sample Output
HINT
2<=N<=500000,S由小写英文字母组成
题解:先跑后缀数组得到height数组,然后我们为了得到∑LCP(i,j),可以转变成求每个height数组对答案做了多少贡献(也就是有多少对LCP(i,j)=height[i])。
根据height数组的定义,两个后缀的LCP=height[i]意味着rank[a]和rank[b]中间的所有height都大于等于height[i],那么我们用两次单调栈处理出height[i]两边第一个比height比i小的数,然后统计一下个数就行了
注意一下height相等的情况,不要重复计算,方法是在两次单调栈中一次用>=,一次用>就行了
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=500010;
int n,m;
int r[maxn],sa[maxn],ra[maxn],rb[maxn],st[maxn],rank[maxn],h[maxn];
int q[maxn],t,ls[maxn],rs[maxn];
long long ans;
char str[maxn];
void work()
{
int i,j,k,p,*x=ra,*y=rb;
for(i=0;i<n;i++) st[x[i]=r[i]]++;
for(i=1;i<m;i++) st[i]+=st[i-1];
for(i=n-1;i>=0;i--) sa[--st[x[i]]]=i;
for(j=p=1;p<n;j<<=1,m=p)
{
for(i=n-j,p=0;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=0;i<m;i++) st[i]=0;
for(i=0;i<n;i++) st[x[y[i]]]++;
for(i=1;i<m;i++) st[i]+=st[i-1];
for(i=n-1;i>=0;i--) sa[--st[x[y[i]]]]=y[i];
for(swap(x,y),i=p=1,x[sa[0]]=0;i<n;i++)
x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j])?p-1:p++;
}
for(i=1;i<n;i++) rank[sa[i]]=i;
for(i=k=0;i<n-1;h[rank[i++]]=k)
for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
}
int main()
{
scanf("%s",str),m=27,n=strlen(str);
int i;
for(i=0;i<n;i++) r[i]=str[i]-'a'+1;
n++,work(),n--;
h[0]=h[n+1]=-1;
for(i=1,t=0;i<=n;i++)
{
while(t&&h[q[t]]>=h[i]) t--;
ls[i]=q[t],q[++t]=i;
}
for(i=n,t=0,q[0]=n+1;i>=1;i--)
{
while(t&&h[q[t]]>h[i]) t--;
rs[i]=q[t],q[++t]=i;
}
ans=(long long)n*(n-1)*(n+1)/2;
for(i=1;i<=n;i++) ans-=(long long)h[i]*(i-ls[i])*(rs[i]-i)*2;
printf("%lld",ans);
return 0;
}
【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈的更多相关文章
- bzoj3238 [Ahoi2013]差异 后缀数组+单调栈
[bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...
- 【BZOJ-3238】差异 后缀数组 + 单调栈
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1561 Solved: 734[Submit][Status] ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- [AHOI2013] 差异 - 后缀数组,单调栈
[AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...
- 【bzoj3238】差异[AHOI2013](后缀数组+单调栈)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 这道题从大概半年以前就开始啃了,不过当时因为一些细节没调出来,看了Sakits神犇 ...
- [BZOJ3238][AHOI2013]差异(后缀数组)
求和式的前两项可以直接算,问题是对于每对i,j计算LCP. 一个比较显然的性质是,LCP(i,j)是h[rk[i]+1~rk[j]]中的最小值. 从h的每个元素角度考虑,就是对每个h计算有多少对i,j ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...
- bzoj 3238: [Ahoi2013]差异 -- 后缀数组
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...
随机推荐
- Tomcat 文件夹结构
文件夹 描写叙述 /bin ...
- [svc]influxdb+grafana实战-各省份api访问成功率统计
简单说下需求: 统计各个省份的 3大运营商的接口访问成功率,绘图展示 数据格式 {"mobile" : "15812345608", "provinc ...
- Delphi记录record中的变体
program Day4; {$APPTYPE CONSOLE} uses SysUtils, Util in 'Util.pas'; type TPerson = packed record ID ...
- C#实现麦克风採集与播放
在网络聊天系统中.採集麦克风的声音并将其播放出来.是最基础的模块之中的一个.本文我们就介绍怎样高速地实现这个基础模块. 一. 基础知识 有几个与声音採集和播放相关的专业术语必需要先了解一下,否则.后面 ...
- Nokia Imaging SDK
Nokia Imaging SDK 目前为 beta 版本,是诺基亚在自己的图像应用中使用的技术同时提供给开发者 使用.这是一个运行在手机设备上处理图片数据的高效的类库.功能包括 JEPG 图片的编码 ...
- systemd启动多实例
最近用了centos7,启动管理器用的是systemd,感觉很好玩. 1.开机自动启动 新建一个service文件放到/usr/lib/systemd/system/ 比如: [Unit] Descr ...
- 改进cocos2dx中lua读ccb的方法
cocos2dx自带的CCBProxy真弱,还好提供了一个CCBReaderLoader.lua,但是也不好用, 于是修改了一下CCBReaderLoader,下面直接贴代码了. function N ...
- st16c554
/* * st16c554.c * * TWO ST16C554 driver for AMCC PPC405EP * * Author: Li Zhi You/Zhu jiang <godis ...
- TVS二极管的主要参数与选型
TVS二极管的主要参数--转载 处理瞬时脉冲对器件损害的最好办法是将瞬时电流从敏感器件引开.TVS二极管在线路板上与被保护线路并联,当瞬时电压超过电路正常工作电压后,TVS二极管便发生雪崩,提供给瞬时 ...
- Go语言入门系列2 基本语法
get download and install packages and dependencies install = compile and install packages and depend ...