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. 【BZOJ4872】【SHOI2017】分手是祝愿 期望DP

    题目大意 有\(n\)盏灯和\(n\)个开关,初始时有的灯是亮的,有的灯是暗的.按下第\(i\)个开关会使第\(j\)盏灯的状态被改变,其中\(j|i\).每次你会随机操作一个开关,直到可以通过不多于 ...

  2. MT【276】正切的半角公式

    若$\Delta ABC$满足:$\tan\dfrac{A}{2}\cdot\tan\dfrac{C}{2}=\dfrac{1}{3},b=\dfrac{4}{3}a$,则$\sin B=$_____ ...

  3. 扩展资源服务器解决oauth2 性能瓶颈

    OAuth用户携带token 请求资源服务器资源服务器拦截器 携带token 去认证服务器 调用tokenstore 对token 合法性校验资源服务器拿到token,默认只会含有用户名信息通过用户名 ...

  4. Hdoj 1115.Lifting the Stone 题解

    Problem Description There are many secret openings in the floor which are covered by a big heavy sto ...

  5. [CF52C]Circular RMQ【线段树】

    题目大意 给你一个环形数列,完成环形数列上区间加法和区间求最小值. 分析 算是一道比较水的线段树模板题. 如果l>r的话,那么修改l,n和1,r区间. 不然的话那么就修改l,r区间. 其他的基础 ...

  6. 面试---Python中的模块和包是什么?

    python模块是: 自我包含并且有组织的代码片段为模块. 表现形式为:写的代码保存为文件.这个文件就是一个模块.sample.py 其中文件名smaple为模块名字. python包是: 包是一个有 ...

  7. 【bfs】献给阿尔吉侬的花束

    [题目描述] 阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫.今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪.现在研究员们想 ...

  8. 在centos7下用http搭建配置svn服务

    应用场景:SVN是Subversion的简称,是一个开放源代码的版本控制系统. 安装环境:centos7  //已关闭 Selinux和 Firewall 配置步骤: 1. 安装HTTP和SVN相关软 ...

  9. hdu 1527 (威佐夫博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1527 Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石 ...

  10. javascript正则表达式---正向预查

    什么是正向预查?这里有腾讯招聘的一个例子: 如何给一串数字用千分制表示?比如9999999999变成9,999,999,999.这样一个问题你会怎么答呢?博主js正则学的不咋样,然后用操作字符串的办法 ...