Time:2016.08.15
Author:xiaoyimi
转载注明出处谢谢
如果有不明白的地方可以在下面评论问我


传送门
思路:
建立后缀数组求出Height
如果说对每次询问暴力求LCP累加的话,每次询问的复杂度是O(n2)(n^2),显然不能接受
考虑每次询问按rank排序后用单调栈维护,使栈中的元素所表示的LCP单调不减
栈中元素的LCP实际上是一段连续元素(至少为1)的LCP值,所以要记录这段连续元素的siz
(siz[i]指元素i所指向的LCP的元素个数,就是这个LCP要被计算的次数)
记录临时变量sum和相邻后缀间的LCP即可
复杂度O(nlogn+mlogn)O(nlogn+mlogn)
注意:
好久没写后缀数组了,板子敲了半天敲不对,height和rank的下标弄不对
老年人
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<stack>
#include<cmath>
#define M 500003
#define LL long long
using namespace std;
int n,m,t;
int cnt[M],rank[M],sa[M],id[M],w[M],tmp[M],height[M],q[M<<3],siz[M];
int f[M][20];
stack <int> S;
bool cmp(int x,int y){return rank[x-1]<rank[y-1];}
int in()
{char ch=getchar();int t=0;while (!isdigit(ch)) ch=getchar();while (isdigit(ch)) t=(t<<3)+(t<<1)+ch-48,ch=getchar();return t;
}
void SA(int len,int up)
{int *rk=rank,p=0,*t=tmp,d=1;for (int i=0;i<len;i++) cnt[rk[i]=w[i]]++;for (int i=1;i<up;i++) cnt[i]+=cnt[i-1];for (int i=len-1;i>=0;i--) sa[--cnt[rk[i]]]=i;for (;;){for (int i=len-d;i<len;i++) id[p++]=i;for (int i=0;i<len;i++)if (sa[i]>=d) id[p++]=sa[i]-d;for (int i=0;i<up;i++) cnt[i]=0;for (int i=0;i<len;i++) cnt[t[i]=rk[id[i]]]++;for (int i=1;i<up;i++) cnt[i]+=cnt[i-1];for (int i=len-1;i>=0;i--) sa[--cnt[t[i]]]=id[i];swap(t,rk);p=1;rk[sa[0]]=0;for (int i=0;i<len-1;i++)if (sa[i]+d<len&&sa[i+1]+d<len&&t[sa[i]]==t[sa[i+1]]&&t[sa[i]+d]==t[sa[i+1]+d])rk[sa[i+1]]=p-1;elserk[sa[i+1]]=p++;if (p==len) break;d<<=1;up=p;p=0;}
}
void Height(int len)
{for (int i=1;i<=len;i++) rank[sa[i]]=i;int k=0,x;for (int i=0;i<len;i++){k=max(k-1,0);x=sa[rank[i]-1];while (w[i+k]==w[x+k]) k++;height[rank[i]]=k;}
}
int LCP(int x,int y)
{if (x>y) swap(x,y);int p=log2(y-x);return min(f[x+1][p],f[y-(1<<p)+1][p]);
}
main()
{n=in();m=in();for (int i=0;i<n;i++){char ch=getchar();while (ch>'z'||ch<'a') ch=getchar();w[i]=ch-'a'+1; } SA(n+1,28);Height(n);for (int i=1;i<=n;i++) f[i][0]=height[i];for (int i=1;(1<<i)<=n;i++)for (int j=1;j+(1<<i)-1<=n;j++)f[j][i]=min(f[j][i-1],f[j+(1<<i-1)][i-1]);for (;m;m--){t=in();for (int i=1;i<=t;i++) q[i]=in();sort(q+1,q+t+1,cmp);t=unique(q+1,q+t+1)-q-1;LL ans=0,sum=0;for (;!S.empty();S.pop());for (int i=2;i<=t;i++){siz[i]=1;tmp[i]=LCP(rank[q[i-1]-1],rank[q[i]-1]);while (!S.empty()&&tmp[S.top()]>tmp[i])sum=sum-(LL)(tmp[S.top()]-tmp[i])*siz[S.top()],siz[i]+=siz[S.top()],S.pop();sum+=tmp[i];ans+=sum;S.push(i);}printf("%lld\n",ans);}
}

【BZOJ3879】SvT,后缀数组+单调栈维护sum相关推荐

  1. 【BZOJ3238】差异,后缀数组+单调栈维护height

    Time:2016.05.23 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 题意已经说的很明白了. 关键在于如何快速求得各lcp的和 有一个重要的性质 排名为i和j(i<j ...

  2. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]

    题目地址 - GO-> 题目大意: 给定一个长度为 nn 的字符串SS,令TiTi表示它从第ii个字符开始的后缀,求以下这个式子的值: ∑1≤i<j≤nlen(Ti)+len(Tj)−2× ...

  3. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  4. POJ - 3415 Common Substrings(后缀数组+单调栈)

    题目链接:点击查看 题目大意:给出两个字符串,再给出一个k,问两个字符串中长度大于等于k的公共子串有多少个(种类可重复) 题目分析:因为涉及到了子串问题,先用后缀数组跑出height数组来,接下来如果 ...

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

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

  6. [Ahoi2013]差异[后缀数组+单调栈]

    链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...

  7. [bzoj3238]差异(后缀数组+单调栈)

    显然我们可以先把len(Ti)+len(Tj)的值先算出来,再把LCP减去.所有len(Ti)+len(Tj)的值为n*(n-1)*(n+1)/2,这个随便在纸上画一画就可以算出来的. 接下来问题就是 ...

  8. POJ 3415 后缀数组+单调栈

    题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉 ...

  9. bzoj 3238: [Ahoi2013]差异(后缀数组+单调栈)

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 3443  Solved: 1562 [Submit][Stat ...

最新文章

  1. aurora IP中选择了小端支持,但小端体现在了什么地方呢?
  2. 华为xs第几批升级鸿蒙,华为和荣耀老机型用户有福:确定能批量升级到鸿蒙系统!...
  3. [翻译]Keeping your JavaScript out of the global scope
  4. java jvm调优_(第1部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...
  5. 1005:I Think I Need a Houseboat-poj
  6. tortoisesvn创建部署项目_FrameWork如何进行云托管部署
  7. k8s 组件介绍-API Server
  8. 第六届省赛(软件类)真题----Java大学C组答案及解析
  9. 灰度值取值范围_第三章 灰度变换与空间滤波-(三)直方图之直方图均衡
  10. android常用的工厂模式,Android的设计模式-简单工厂模式
  11. 为什么要打jar_为什么海带要打一个结?
  12. inDesign文字教程,如何制作复古文本效果?
  13. 我用 Python 分析1585家电商车厘子销售数据,发现这些秘密
  14. creo打不开stp文件_为什么stp网站打不开 creo打不开stp文件
  15. 使用Java SE8 Streams 处理数据,Part 2
  16. HDU2370——Convert Kilometers to Miles
  17. jenkins报错:java.lang.illegalstateexception already existed will not overwrite with
  18. html图片长高如何设置,快速长高的方法 教你一个动作暴长10cm
  19. 尚硅谷_在线教育_Nuxt整合错误
  20. 格式工厂视频压缩转码选择

热门文章

  1. Apache软件基金会Member陈亮:一名开源拓荒者的 Apache之旅
  2. 【华为云实战开发】15.Maven依赖的JAR包下载慢?赶紧看过来
  3. 红橙Darren视频笔记 手写ButterKnife(Android Studio4.2.2 gradle-6.7.1 )
  4. Head First设计模式读书笔记二 观察者模式
  5. LaTeX youngtab包——组合数学中棋盘格的绘制
  6. 【方便自己使用】KKT条件
  7. java awt 边距_Java Swing - 使用Line Border在TextArea上设置边距
  8. loading窗口动画 web_在页面未加载完之前显示loading动画
  9. 识别图片噪声干扰_射频相位噪声介绍
  10. 【数据库基础知识】数据库表格——主键和外键