bzoj 3879: SvT
Description
(我并不想告诉你题目名字是什么鬼)
有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n].
现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始位置来表示),求这些后缀两两之间的LCP(LongestCommonPrefix)的长度之和.一对后缀之间的LCP长度仅统计一遍.
Input
第一行两个正整数n,m,分别表示S的长度以及询问的次数.
接下来一行有一个字符串S.
接下来有m组询问,对于每一组询问,均按照以下格式在一行内给出:
首先是一个整数t,表示共有多少个后缀.接下来t个整数分别表示t个后缀在字符串S中的出现位置.
Output
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long i64;
const int N=1e6+;
char s[N];
int nx[N][],l[N],fa[N],pp=,pv=;
int n,m,pos[N];
int e0[N],es[N],enx[N],ep=,sz[N],son[N],dep[N],top[N],id[N][],idp=,ss[N],sp=;
int ed[N],tk=;
char buf[],*ptr=buf-;
int _(){
int x=;
while(*ptr<)++ptr;
while(*ptr>)x=x*+*ptr++-;
return x;
}
void _(char*s){
while(*ptr<)++ptr;
while(*ptr>)*s++=*ptr++;
*ptr=;
}
int ins(int x){
int p=pv,np=++pp;
l[np]=l[p]+;
while(p&&!nx[p][x])nx[p][x]=np,p=fa[p];
if(!p)fa[np]=;
else{
int q=nx[p][x];
if(l[q]==l[p]+)fa[np]=q;
else{
int nq=++pp;
l[nq]=l[p]+;
memcpy(nx[nq],nx[q],sizeof(nx[]));
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
while(p&&nx[p][x]==q)nx[p][x]=nq,p=fa[p];
}
}
return pv=np;
}
void push(int w){
ss[++sp]=w;
id[w][]=++idp;
dep[w]=dep[fa[w]]+;
}
void hld_pre(){
for(int i=;i<=pp;++i){
es[ep]=i;enx[ep]=e0[fa[i]];e0[fa[i]]=ep++;
sz[i]=;
}
push();
while(sp){
int w=ss[sp],&e=e0[w];
if(!e){
int f=fa[w];
sz[f]+=sz[w];
if(w[sz]>f[son][sz])f[son]=w;
id[w][]=idp;
--sp;
continue;
}
int u=es[e];
e=enx[e];
push(u);
}
for(int i=;i<=pp;++i)if(i[fa][son]!=i){
for(int w=i;w;w=w[son])w[top]=i;
}
}
int lca(int x,int y){
int a=top[x],b=top[y];
while(a!=b){
if(dep[a]>dep[b])x=fa[a],a=top[x];
else y=fa[b],b=top[y];
}
return dep[x]<dep[y]?x:y;
}
bool cmp(int a,int b){
return id[a][]<id[b][];
}
int cs[N],cp,tp[N],_f[N];
void cal(){
i64 ans=;
int p=;
_f[ss[++sp]=cs[p++]]=;
while(sp){
int w=ss[sp];
if(p<cp&&id[cs[p]][]<=id[w][])_f[ss[++sp]=cs[p++]]=w;
else{
--sp;
int f=_f[w];
if(f>){
ans+=i64(l[f])*tp[f]*tp[w];
tp[f]+=tp[w];
}
}
}
printf("%lld\n",ans);
}
int main(){
fread(buf,,sizeof(buf),stdin)[buf]=;
n=_();m=_();
_(s+);
for(int i=n;i;--i)pos[i]=ins(s[i]-'a');
hld_pre();
for(int c;m;--m){
c=_();
cp=;
++tk;
for(int i=,x;i<c;++i){
x=pos[_()];
if(ed[x]!=tk)ed[cs[cp++]=x]=tk,tp[x]=;
}
std::sort(cs,cs+cp,cmp);
c=cp;
for(int i=,pv=;i<c;++i){
int x=lca(cs[i],pv);
pv=cs[i];
if(ed[x]!=tk)ed[cs[cp++]=x]=tk,tp[x]=;
}
std::sort(cs,cs+cp,cmp);
cal();
}
return ;
}
bzoj 3879: SvT的更多相关文章
- ●BZOJ 3879 SvT
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3879 题解: 后缀数组,单调栈,RMQ 其实类似 BZOJ 3238 [Ahoi2013]差 ...
- BZOJ 3879: SvT [虚树 后缀树]
传送门 题意: 多次询问,给出一些后缀,求两两之间$LCP$之和 哈哈哈哈哈哈哈竟然$1A$了,刚才还在想如果写不好这道题下节数学就不上了,看来是上天让我上数学课啊 $Suffix\ Virtual\ ...
- BZOJ 3879: SvT 虚树 + 后缀自动机
Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...
- 【BZOJ 3879】SvT
http://www.lydsy.com/JudgeOnline/problem.php?id=3879 SvT的中文是后缀虚树? 反正本蒟蒻不懂,还是$O(nlogn)$的后缀数组和单调栈维护来做, ...
- bzoj 3879 虚树
题目大意: 给一个字符串,多次询问k个后缀,求它们两两间LCP长度总和 分析: 转化为后缀树,用虚树求 注意: 后缀树中代表后缀的点都是叶子节点 题目中取模并没有卵用 #include <cst ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- Week Four
2018.12.18 1.[USACO Platinum C] 2.[Gym 102028H] 3.[BZOJ 2750] 4.[BZOJ 3238] 5.[BZOJ 4310] 6.[BZOJ 38 ...
- Week Five
2018.12.25 1.[BZOJ 4310] 2.[BZOJ 3879] 3.[BZOJ 2754] 4.[BZOJ 4698] 5.[Codeforces 914E] 6.[Codeforces ...
- HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)
http://acm.hdu.edu.cn/showproblem.php?pid=3879 http://www.lydsy.com/JudgeOnline/problem.php?id=1497 ...
随机推荐
- ZOJ 3541 The Last Puzzle(经典区间dp)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3541 题意:有一排开关,有个开关有两个值t和d,t是按下开关后在t秒后会自 ...
- Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister
http://codeforces.com/contest/812/problem/B 题意: 有n层楼,每层楼有m个房间,1表示灯开着,0表示灯关了.最两侧的是楼梯. 现在每从一个房间移动到另一个房 ...
- 51Nod 1557 两个集合(二分)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1557 题意: 小X有n个互不相同的整数: p1,p2,...,pn .他 ...
- POJ 1034 The dog task(二分图匹配)
http://poj.org/problem?id=1034 题意: 猎人和狗一起出去,狗的速度是猎人的两倍,给出猎人的路径坐标,除了这些坐标外,地图上还有一些有趣的点,而我们的狗,就是要尽量去多的有 ...
- BZOJ 1951 【SDOI2010】 古代猪文
题目链接:古代猪文 好久没写博客了,这次就先写一篇吧…… 题面好鬼……概括起来就是:给出\(N,G(\leqslant 10^9)\),求:\[G^{\sum_{d|n}\binom{n}{d}} \ ...
- thinkphp3.2笔记(4)模板函数的使用 foreach标签
一 模板函数的使用 1.代码 效果: 函数会按照从左到右的顺序依次调用.如果你觉得这样写起来比较麻烦,也可以直接这样写:{:substr(strtoupper(md5($name)),0,3)} 默 ...
- 转 CentOS 7 minimal 版本安装后网络配置
转自[http://www.07net01.com/2016/01/1140061.html] 1.首先使用root登录服务器,输入 nmcli d 我们发现网卡是处于禁用状态. 2.打开网络管理器界 ...
- C#并行编程(1)
一.基于任务的程序设计 共享内存多核OS和分布式内存OS 共享内存多核OS-一个微处理器由多个内核组成,且每个内核共享一段私有内存: 分布式内存OS-- 由多个微处理器组成,每个微处理器可以有自己的私 ...
- intent 系统设置界面
开发Android软件时,常常需要打开系统设置或信息界面,来设置相关系统项或查看系统的相关信息,这时我们就可以使用以下语句来实现:(如打开“无线和网络设置”界面) Intent intent = ...
- java生成doc和jar
生成doc帮助文档. 第一步,需要有一个java类,里面封装了各种方法 第二部,给类和方法添加注释文档 注释文档格式: /** * */ @author 作者 @version 版本 @return ...