BZOJ 3879: SvT [虚树 后缀树]
题意:
多次询问,给出一些后缀,求两两之间$LCP$之和
哈哈哈哈哈哈哈竟然$1A$了,刚才还在想如果写不好这道题下节数学就不上了,看来是上天让我上数学课啊
$Suffix\ Virtual\ Tree$
没有多次询问就是那道差异了
多次询问总次数$O(n)$,建出后缀树每次建虚树就行了
然后询问给出的是后缀,用一个$pos$映射到后缀树上的点
然后$Right$集合要在$DP$的时候递推
貌似还有后缀数组的做法跑的好快
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e6+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,Q;
char s[N];
struct State{
int ch[],par,val;
}t[N];
int sz=,root=,last=;
int pos[N];
void extend(int c){
int p=last,np=++sz;
t[np].val=t[p].val+;
for(;p&&!t[p].ch[c];p=t[p].par) t[p].ch[c]=np;
if(!p) t[np].par=root;
else{
int q=t[p].ch[c];
if(t[q].val==t[p].val+) t[np].par=q;
else{
int nq=++sz;
t[nq]=t[q];t[nq].val=t[p].val+;
t[q].par=t[np].par=nq;
for(;p&&t[p].ch[c]==q;p=t[p].par) t[p].ch[c]=nq;
}
}
last=np;
} struct Edge{
int v,ne;
}e[N];
int cnt,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
int dfn[N],dfc,fa[N][],deep[N];
void dfs(int u){
dfn[u]=++dfc;
for(int i=;(<<i)<=deep[u];i++)
fa[u][i]=fa[ fa[u][i-] ][i-];
for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa[u][]){
fa[e[i].v][]=u;
deep[e[i].v]=deep[u]+;
dfs(e[i].v);
}
}
inline int lca(int x,int y){
if(deep[x]<deep[y]) swap(x,y);
int bin=deep[x]-deep[y];
for(int i=;i>=;i--)
if((<<i)&bin) x=fa[x][i];
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return x==y ? x : fa[x][];
} inline bool cmp(int x,int y){return dfn[x]<dfn[y];}
int st[N],key[N],a[N];
int d[N];
ll ans;
void dp(int u){
d[u]=key[u] ? : ;
for(int i=h[u];i;i=e[i].ne){
dp(e[i].v);
ans+=(ll)d[u]*d[e[i].v]*t[u].val;
d[u]+=d[e[i].v];
}
h[u]=;
}
void VirTree(){
cnt=;
int n=read();
for(int i=;i<=n;i++) a[i]=pos[read()];
sort(a+,a++n);
int p=;a[++p]=a[];
for(int i=;i<=n;i++) if(a[i]!=a[i-]) a[++p]=a[i];
n=p;
sort(a+,a++n,cmp);
for(int i=;i<=n;i++) key[a[i]]=; int top=;
for(int i=;i<=n;i++){
if(!top) {st[++top]=a[i];continue;}
int x=a[i],f=lca(x,st[top]);
while(dfn[f]<dfn[st[top]]){
if(dfn[f]>=dfn[st[top-]]){
ins(f,st[top--]);
if(f!=st[top]) st[++top]=f;
break;
}else ins(st[top-],st[top]),top--;
}
st[++top]=x;
}
while(top>) ins(st[top-],st[top]),top--; ans=;
dp(st[]);
printf("%lld\n",ans);
for(int i=;i<=n;i++) key[a[i]]=;
} int main(){
freopen("in","r",stdin);
n=read();Q=read();
scanf("%s",s+);
reverse(s+,s++n);
for(int i=;i<=n;i++) extend(s[i]-'a'),pos[n-i+]=last;
for(int i=;i<=sz;i++) ins(t[i].par,i);
dfs(root);
memset(h,,sizeof(h));
while(Q--) VirTree();
}
BZOJ 3879: SvT [虚树 后缀树]的更多相关文章
- BZOJ 3879: SvT 虚树 + 后缀自动机
Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
- 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树
另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...
- uoj 131/bzoj 4199 [NOI2015]品酒大会 后缀树+树d
题目大意 见uoj131 分析 题目的提示还是很明显的 \(r\)相似就就代表了\(0...r-1\)相似 建出后缀树我们能dfs算出答案 再后缀和更新一下即可 注意 细节挺多的,但数据很良心 不然我 ...
- BZOJ 2555 SubString(LCT+后缀树)
喜闻乐见的LCT+SAM 此题要求动态插入,直接上后缀树.然后询问其实就是求一个节点的子树后缀结束节点的个数. 因为建立后缀树需要插入和删除,就直接上LCT.每次加入一个点,把它到根的路径加一 (现在 ...
- bzoj 3879: SvT
Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...
- bzoj 4199: [Noi2015]品酒大会 后缀树
题目大意: 给定一个长为n的字符串,每个下标有一个权\(w_i\),定义下标\(i,j\)是r相似的仅当\(r \leq LCP(suf(i),suf(j))\)且这个相似的权为\(w_i,w_j\) ...
- ●BZOJ 3879 SvT
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3879 题解: 后缀数组,单调栈,RMQ 其实类似 BZOJ 3238 [Ahoi2013]差 ...
- [模板] 后缀自动机&&后缀树
后缀自动机 后缀自动机是一种确定性有限状态自动机, 它可以接收字符串\(s\)的所有后缀. 构造, 性质 翻译自毛子俄罗斯神仙的博客, 讲的很好 后缀自动机详解 - DZYO的博客 - CSDN博客 ...
随机推荐
- Palindromes
http://acm.hdu.edu.cn/showproblem.php?pid=1318 Palindromes Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 1562 Oil Deposits
题目: The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. G ...
- YUI 的模块信息配置优先级关系梳理
背景 YUI的配置参数较多, 可以在好几个地方配置一个module的相关信息, 如: //在全局配置, 所以YUI实例共享 YUI_config = { modules: { 'w-autcomple ...
- 转:绝对干货--WordPress自定义查询wp_query所有参数详细注释
<?php /** * WordPress 查询综合参考 * 编译:luetkemj - luetkemj.com * * 官方文档: http://codex.wordpress.org/Cl ...
- debian 9 双显卡安装NVIDIA显卡驱动
最近用debian,给debian装n卡驱动折腾了好几天了,主要还是网络不好,官方wiki的方法下载经常卡死..摸索了几天感觉已经摸到了头绪,决定写下来供大家参考参考 先提供单显卡NVIDIA驱动的安 ...
- VS的无用文件
目录:C:\ProgramData\Microsoft Visual Studio\10.0\TraceDebugging 每次调试程序都会产生30MB左右大小的Debug文件.如何禁止? Tools ...
- HTTP协议的简单介绍
前传:HTTP协议的演变过程 HTTP(HyperText Transfer Protocol)协议是基于TCP的应用层协议,它不关心数据传输的细节,主要是用来规定客户端和服务端的数据传输格式,最初是 ...
- J.U.C JMM. pipeline.指令重排序,happen-before(续MESI协议)
缓存(Cache) CPU的读/写(以及取指令)单元正常情况下甚至都不能直接访问内存——这是物理结构决定的:CPU都没有管脚直接连到内存.相反,CPU和一级缓存(L1 Cache)通讯,而 ...
- c#动态编译并执行字符串
比较简单,步骤是这样的 string -> compiler -> assembly -> reflection -> execution 直接上代码: using Syste ...
- linux_远程连接
为什么要远程连接linux服务器? 温度.湿度.电力各种影响,有的企业使用阿里云服务器,更加接触不到机房,所有需要通过远程连接服务器来进行管理 IP地址? 互联网上的计算机,都会有一个唯一的32位地址 ...