https://www.lydsy.com/JudgeOnline/problem.php?id=3879

把所有的后缀取出,按rank排序

求出相邻两个后缀的lcp

每个后缀对答案的贡献就是 与在它之前的后缀的lcp之和

维护一个单调递增的栈,记录栈中元素的lcp之和 即可

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4.  
  5. using namespace std;
  6.  
  7. #define N 500001
  8. #define M 3000001
  9.  
  10. int n,m,mm;
  11. char s[N];
  12. int a[N];
  13.  
  14. int b[M],r[N];
  15.  
  16. int v[N];
  17. int p,q=,k;
  18. int sa[][N],rk[][N];
  19.  
  20. int height[N],h[N];
  21. int st[N][];
  22.  
  23. int Log[N];
  24.  
  25. int ST[N],top;
  26. int num[N],val[N];
  27.  
  28. void read(int &x)
  29. {
  30. x=; char c=getchar();
  31. while(!isdigit(c)) c=getchar();
  32. while(isdigit(c)) { x=x*+c-''; c=getchar(); }
  33. }
  34.  
  35. void mul(int *sa,int *rk,int *SA,int *RK)
  36. {
  37. for(int i=;i<=n;++i) v[rk[sa[i]]]=i;
  38. for(int i=n;i;--i) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k;
  39. for(int i=n-k+;i<=n;++i) SA[v[rk[i]]--]=i;
  40. for(int i=;i<=n;++i) RK[SA[i]]=RK[SA[i-]]+(rk[SA[i]]!=rk[SA[i-]] || rk[SA[i]+k]!=rk[SA[i-]+k]);
  41. }
  42.  
  43. void presa()
  44. {
  45. for(int i=;i<=n;++i) v[a[i]]++;
  46. for(int i=;i<=;++i) v[i]+=v[i-];
  47. for(int i=;i<=n;++i) sa[p][v[a[i]]--]=i;
  48. for(int i=;i<=n;++i) rk[p][sa[p][i]]=rk[p][sa[p][i-]]+(a[sa[p][i]]!=a[sa[p][i-]]);
  49. for(k=;k<n;k<<=,swap(p,q)) mul(sa[p],rk[p],sa[q],rk[q]);
  50. }
  51.  
  52. void get_height()
  53. {
  54. int k=,j;
  55. for(int i=;i<=n;++i)
  56. {
  57. j=sa[p][rk[p][i]-];
  58. while(a[i+k]==a[j+k]) k++;
  59. height[rk[p][i]]=k;
  60. if(k) k--;
  61. }
  62. }
  63.  
  64. void prest()
  65. {
  66. for(int i=;i<=n;++i) st[i][]=height[i];
  67. for(int i=,k=;i<=;++i,k<<=)
  68. for(int j=;j+k-<=n;++j)
  69. st[j][i]=min(st[j][i-],st[j+k/][i-]);
  70. }
  71.  
  72. int get(int i,int j)
  73. {
  74. i++;
  75. int l=Log[j-i+];
  76. return min(st[i][l],st[j-(<<l)+][l]);
  77. }
  78.  
  79. void solve()
  80. {
  81. for(int i=;i<=mm;++i) r[i]=rk[p][b[i]];
  82. sort(r+,r+mm+);
  83. for(int i=;i<=mm;++i) h[i]=get(r[i-],r[i]);
  84. top=;
  85. int tmp_num;
  86. long long now=,ans=;
  87. for(int i=;i<=mm;++i)
  88. {
  89. tmp_num=;
  90. while(top && h[i]<=h[ST[top]])
  91. {
  92. now-=1LL*num[top]*val[top];
  93. tmp_num+=num[top--];
  94. }
  95. tmp_num++;
  96. ST[++top]=i;
  97. num[top]=tmp_num;
  98. val[top]=h[i];
  99. now+=1LL*tmp_num*h[i];
  100. ans+=now;
  101. }
  102. cout<<ans<<'\n';
  103. }
  104.  
  105. int main()
  106. {
  107. int T;
  108. read(n); read(T);
  109. for(int i=;i<=n;++i) Log[i]=Log[i>>]+;
  110. scanf("%s",s+);
  111. for(int i=;i<=n;++i) a[i]=s[i]-'a'+;
  112. presa();
  113. get_height();
  114. prest();
  115. while(T--)
  116. {
  117. read(m);
  118. for(int i=;i<=m;++i) read(b[i]);
  119. sort(b+,b+m+);
  120. mm=unique(b+,b+m+)-b-;
  121. solve();
  122. }
  123. }

bzoj千题计划313:bzoj3879: SvT(后缀数组+st表+单调栈)的更多相关文章

  1. bzoj千题计划314:bzoj3238: [Ahoi2013]差异(后缀数组+st表+单调栈)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3238 跟 bzoj3879 差不多 #include<cstdio> #include ...

  2. BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]

    4453: cys就是要拿英魂! Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 46[Submit][Status][Discu ...

  3. 【bzoj3879】SvT 后缀数组+倍增RMQ+单调栈

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

  4. SPOJ 687 Repeats(后缀数组+ST表)

    [题目链接] http://www.spoj.com/problems/REPEATS/en/ [题目大意] 求重复次数最多的连续重复子串的长度. [题解] 考虑错位匹配,设重复部分长度为l,记s[i ...

  5. POJ 3693 Maximum repetition substring(后缀数组+ST表)

    [题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...

  6. BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay

    BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...

  7. UVA10829 L-Gap Substrings(后缀数组+ST表)

    后缀数组+ST表. 代填的坑. \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long using namespace ...

  8. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

  9. bzoj千题计划312:bzoj2119: 股市的预测(后缀数组+st表)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2119 题意:将给定数组差分后,求ABA形式的字串个数,要求|B|=m,|A|>0 1.后缀数 ...

随机推荐

  1. Install KVM Hypervisor on arrch64 Linux Server

    Install KVM Hypervisor on arrch64 Linux Server 参考链接: https://wiki.ubuntu.com/ARM64/QEMU https://wiki ...

  2. Vue组件之间数据交互与通信

    Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 一.父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传 ...

  3. 第一次使用cisco packet tracer

    搭建一个如图所示的网络,左边局域网是10.0.0.0网段,右边局域网是12.0.0.0网段,中间为广域网11.0.0.0网段 上面的成功了,但是不是很熟悉,下面重新来一遍 1.先用可视化界面建立一个如 ...

  4. luogu3119/bzoj3887 草鉴定 (tarjan缩点+spfa)

    首先缩一波点,就变成了一个DAG,边权是出点的大小 那我们走到某个点的时候可能会有两种状态:已经走过反边或者没走过 于是就把一个点拆成两层(x和x+N),第二层的点表示我已经走过反边了,每层中的边和原 ...

  5. BZOJ5262(容斥)

    题目描述 听着自己美妙的曲子,小Z进入了梦乡.在梦中,小Z仿佛又回到了自己纵横考场的年代.在梦中,小Z参加了一场 考试,这场考试一共有n道题,每道题的最终得分都是一个大于等于0的整数.然而醒来后,小Z ...

  6. WebService学习总结(一)——WebService的相关概念

    一.序言 大家或多或少都听过 WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成 分.但是不得不承认的是W ...

  7. wave

    题意:求有多少个1~n的排列满足: 其中n<=50 解: 贼神的一道题. 如何处理绝对值? 从小到大按顺序放数,可以拆掉绝对值. 如果你放的旁边有个空隙,那么贡献-i,如果旁边有个数,贡献+i ...

  8. MVC过滤器处理Session过期

    一.自定义一个Action过滤器 public class CheckSession: ActionFilterAttribute { public override void OnActionExe ...

  9. SNP在世界地图上的频率分布

    简单介绍两个网页工具,第一个是GGV,其界面如下: 第二个工具是HGDP,个人感觉画出来有点丑..都是同一所大学开发出来的:界面如下:

  10. 第五节,TensorFlow编程基础案例-session使用(上)

    在第一节中我们已经介绍了一些TensorFlow的编程技巧;第一节,TensorFlow基本用法,但是内容过于偏少,对于TensorFlow的讲解并不多,这一节对之前的内容进行补充,并更加深入了解讲解 ...