3238: [Ahoi2013]差异

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 1561  Solved: 734
[Submit][Status][Discuss]

Description

Input

一行,一个字符串S

Output

一行,一个整数,表示所求值

Sample Input

cacao

Sample Output

54

HINT

2<=N<=500000,S由小写英文字母组成

Source

Solution

后缀数组+单调栈

LCP的话,预处理ST表,然后直接求?似乎不好,不过后缀数组的话很好想

肯定是对height做文章...总后缀的长度和很好求..随便一算就出来了...考虑LCP的问题

想法是枚举i,对于每个height[i]前后扩展,找出对答案的贡献,然后最后计算答案..似乎可以,但是WA掉了..

原因是有重复计算,那么要不重复..上述是左右两边扩展,使得区间[l,r]中height[i]为最小,重复的很多,思想还是一样的不过不妨把区间看成[l,r)(PS,其实表述不准确),这样的扩展下去,即向左有限制,向右无限制,向左扩展到相等的就停止,向右遇到相等的可以继续.

那么需要用单调栈去维护扩展的过程..这样就能得到每一个height[i]对答案的贡献了,最后答案需要减掉(i-L[i]+1)*(R[i]-i+1)*(height[i])

注意:

在计算答案的过程中要强制转换.(旧错不再犯)

处理后的单调栈内如果为空,说明可以扩展到开头/结尾(也是看别人的才反应过来的)

PS:正解好像不是这个?...不过POJ上好像做过类似的题,所以写起来还是比较快的..

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 500010
char S[maxn]; int SA[maxn],len;
int ws[maxn],wv[maxn],wa[maxn],wb[maxn];
int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void DA(char *r,int *sa,int n,int m)
{
int p,*x=wa,*y=wb,*t;
for (int i=; i<m; i++) ws[i]=;
for (int i=; i<n; i++) ws[x[i]=r[i]]++;
for (int i=; i<m; i++) ws[i]+=ws[i-];
for (int i=n-; i>=; i--) sa[--ws[x[i]]]=i;
p=; for (int j=; p<n; j*=,m=p)
{
p=; for (int i=n-j; i<n; i++) y[p++]=i;
for (int i=; i<n; i++) if (sa[i]>=j) y[p++]=sa[i]-j;
for (int i=; i<n; i++) wv[i]=x[y[i]];
for (int i=; i<m; i++) ws[i]=;
for (int i=; i<n; i++) ws[wv[i]]++;
for (int i=; i<m; i++) ws[i]+=ws[i-];
for (int i=n-; i>=; i--) sa[--ws[wv[i]]]=y[i];
t=x; x=y; y=t; p=; x[sa[]]=;
for (int i=; i<n; i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
}
int rank[maxn],height[maxn];
void calheight(char *r,int *sa,int n)
{
int k=;
for (int i=; i<=n; i++) rank[sa[i]]=i;
for (int i=; i<n; height[rank[i++]]=k)
{k?k--:;for (int j=sa[rank[i]-]; r[i+k]==r[j+k]; k++);}
}
int stack[maxn],top,L[maxn],R[maxn];
long long tot,lcp;
int main()
{
scanf("%s",S); len=strlen(S); S[len]=;
DA(S,SA,len+,); calheight(S,SA,len);
tot=(long long)((long long)len*(long long)(len-)*(long long)(len+)/);
top=; stack[]=;
for (int i=; i<=len; i++)
{
while (top && height[stack[top-]]>height[i]) top--;
if (top) L[i]=stack[top-]+;
else L[i]=;
stack[top++]=i;
}
top=; stack[]=len;
for (int i=len; i>=; i--)
{
while (top && height[stack[top-]]>=height[i]) top--;
if (top) R[i]=stack[top-]-;
else R[i]=len;
stack[top++]=i;
}
for (int i=; i<=len; i++)
lcp+=(long long)*(long long)(i-L[i]+)*(long long)(R[i]-i+)*(long long)height[i];
printf("%lld\n",tot-lcp);
return ;
}

【BZOJ-3238】差异 后缀数组 + 单调栈的更多相关文章

  1. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  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. bzoj3238 [Ahoi2013]差异 后缀数组+单调栈

    [bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  5. BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈

    BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...

  6. BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)

    BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...

  7. BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】

    题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...

  8. 【BZOJ3879】SvT 后缀数组+单调栈

    [BZOJ3879]SvT Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干 ...

  9. BZOJ_3879_SvT_后缀数组+单调栈

    BZOJ_3879_SvT_后缀数组+单调栈 Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个 ...

随机推荐

  1. java多线程系类:基础篇:05线程的等待与唤醒

    概要 本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. wait()和notify()3. wait(long t ...

  2. SQL Server 查询性能优化 相关文章

    来自: SQL Server 查询性能优化——堆表.碎片与索引(一) SQL Server 查询性能优化——堆表.碎片与索引(二) SQL Server 查询性能优化——覆盖索引(一) SQL Ser ...

  3. Camera.Parameters 参数

    public class Camera.Parameters extends Object java.lang.Object    ↳ android.hardware.Camera.Paramete ...

  4. &12-2 查找二叉搜索树

    #1,定理 在一棵高度为h的二叉搜索树上,动态集合上的操作SEARCH.MINIMUM.MAXIMUM.SUCCESSOR和PREDECESSOR可以在O(h)时间内完成. #2,伪代码 分别是搜索, ...

  5. 航空货运:运价类别Rate Class

    1.普通货物运价(1)基础运价(代号N -注:Normal的首字母)民航总局统一规定各航段货物基础运价为45公斤以下普通货物运价.(2)重量分界点运价(代号Q  -注:Quantity的首字母)国内航 ...

  6. JQuery实现资讯上下滚动悬停效果

    第一步:使用repeater绑定一个table. <table width="530" id="rollBar"> <asp:Repeater ...

  7. java并发:简单面试问题集锦

    多线程:Simultaneous Multithreading,简称SMT. 并行.并发 并行性(parallelism)指两个或两个以上的事件在同一时刻发生,在多道程序环境下,并行性使多个程序同一时 ...

  8. 自己画WinForm 皮肤包括默认控件

    好久没来博客园,今天捣鼓到现在就是为了把之前的皮肤控件完善好, 之前也看了很多技术文章,大多数都是自己重写系统控件实现换肤,几乎没有像东日的(IrisSkin)控件一样 添加一个组件 把系统的皮肤全换 ...

  9. [POJ3696]The Luckiest number(数论)

    题目:http://poj.org/problem?id=3696 题意:给你一个数字L,你要求出一个数N,使得N是L的倍数,且N的每位数都必须是8,输出N的位数(如果不存在输出0) 分析: 首先我们 ...

  10. 最小/大费用最大流模板(codevs1914)

    void addedge(int fr,int to,int cap,int cos){ sid[cnt].fr=fr;sid[cnt].des=to;sid[cnt].cap=cap;sid[cnt ...