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

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

求出相邻两个后缀的lcp

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

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

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 500001
#define M 3000001 int n,m,mm;
char s[N];
int a[N]; int b[M],r[N]; int v[N];
int p,q=,k;
int sa[][N],rk[][N]; int height[N],h[N];
int st[N][]; int Log[N]; int ST[N],top;
int num[N],val[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void mul(int *sa,int *rk,int *SA,int *RK)
{
for(int i=;i<=n;++i) v[rk[sa[i]]]=i;
for(int i=n;i;--i) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k;
for(int i=n-k+;i<=n;++i) SA[v[rk[i]]--]=i;
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]);
} void presa()
{
for(int i=;i<=n;++i) v[a[i]]++;
for(int i=;i<=;++i) v[i]+=v[i-];
for(int i=;i<=n;++i) sa[p][v[a[i]]--]=i;
for(int i=;i<=n;++i) rk[p][sa[p][i]]=rk[p][sa[p][i-]]+(a[sa[p][i]]!=a[sa[p][i-]]);
for(k=;k<n;k<<=,swap(p,q)) mul(sa[p],rk[p],sa[q],rk[q]);
} void get_height()
{
int k=,j;
for(int i=;i<=n;++i)
{
j=sa[p][rk[p][i]-];
while(a[i+k]==a[j+k]) k++;
height[rk[p][i]]=k;
if(k) k--;
}
} void prest()
{
for(int i=;i<=n;++i) st[i][]=height[i];
for(int i=,k=;i<=;++i,k<<=)
for(int j=;j+k-<=n;++j)
st[j][i]=min(st[j][i-],st[j+k/][i-]);
} int get(int i,int j)
{
i++;
int l=Log[j-i+];
return min(st[i][l],st[j-(<<l)+][l]);
} void solve()
{
for(int i=;i<=mm;++i) r[i]=rk[p][b[i]];
sort(r+,r+mm+);
for(int i=;i<=mm;++i) h[i]=get(r[i-],r[i]);
top=;
int tmp_num;
long long now=,ans=;
for(int i=;i<=mm;++i)
{
tmp_num=;
while(top && h[i]<=h[ST[top]])
{
now-=1LL*num[top]*val[top];
tmp_num+=num[top--];
}
tmp_num++;
ST[++top]=i;
num[top]=tmp_num;
val[top]=h[i];
now+=1LL*tmp_num*h[i];
ans+=now;
}
cout<<ans<<'\n';
} int main()
{
int T;
read(n); read(T);
for(int i=;i<=n;++i) Log[i]=Log[i>>]+;
scanf("%s",s+);
for(int i=;i<=n;++i) a[i]=s[i]-'a'+;
presa();
get_height();
prest();
while(T--)
{
read(m);
for(int i=;i<=m;++i) read(b[i]);
sort(b+,b+m+);
mm=unique(b+,b+m+)-b-;
solve();
}
}

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. 【XSY2762】插线板 分块

    题目大意 有\(n\)个插线板,每个插线板会在\(l_i\)时刻初插入到队列中(队列是按插线板的编号排序的),\(r_i\)时刻末移除. 插入一个插线板时会对当前所有接在队列中这个插线的下一个插线板上 ...

  2. 「HDU6158」 The Designer(圆的反演)

    题目链接多校8-1009 HDU - 6158 The Designer 题意 T(<=1200)组,如图在半径R1.R2相内切的圆的差集位置依次绘制1,2,3,到n号圆,求面积之和(n< ...

  3. 编写高质量代码:改善Java程序的151个建议 --[0~25]

    警惕自增的陷阱 public class Client7 { public static void main(String[] args) { int count=0; for(int i=0; i& ...

  4. configure: error: no acceptable C compiler found in $PATH 问题解决

    解决办法: 安装GCC软件套件 [root@localhost ~]# yum install gccLoaded plugins: fastestmirrorLoading mirror speed ...

  5. java 连接数组

    一,使用Apache Commons的ArrayUtils Apache Commons类库有很多,几乎大多数的开源框架都依赖于它,Commons中的工具会节省你大部分时间,它包含一些常用的静态方法和 ...

  6. Max Mex

    Max Mex 无法直接处理 可以二分答案! [0,mid]是否在同一个链上? 可以不修改地做了 修改? 能不能信息合并?可以! 记录包含[l,r]的最短链的两端 可以[0,k][k+1,mid]合并 ...

  7. 使用visual C++测试

    背景:学习一门语言最好的方式就是实际动手敲一遍.现在敲一遍的障碍是不能熟练的使用工具,特此记录下来 新建工程 新建——项目——Windows 控制台应用程序 如何新建测试用例呢? OJ试题在VS201 ...

  8. 浅谈 WebDriver如何应对不同浏览器

    selenium2 基于对象的测试,在selenium2中一共支持以下浏览器: Firefox(FirefoxDriver) IE(InternetExplorerDriver) Chrome(Chr ...

  9. Fiddler安装证书

    1.打开Fiddler,点击工具栏中的Tools——>Fiddler Options…       2.切换到 HTTPS 选项卡,勾选 Capture HTTPS CONNECTs,勾选 De ...

  10. day02作业

    1.判断下列逻辑语句的True,False. 1),1 > 1 or 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6 tru ...