[BZOJ3879] SvT
来源:互联网 发布:海阔淘宝客助手 编辑:程序博客网 时间:2024/06/03 19:16
传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=3879
题目大意
给定一个字符串
每次询问这个字符串得一些后缀两两之间的
题解
建立反串的SAM得到后缀树
求点间的LCP转化为LCA
每次建立虚树就好了
const maxn=500005;type data=record fa,len,key:longint; tranc:array[0..26]of longint; end;var x:array[0..3*maxn]of data; w:array[0..6*maxn,1..2]of longint; fa,t,pos,y,dep,z,clear:array[0..3*maxn]of longint; size:array[0..3*maxn]of longint; st:array[0..3*maxn,0..20]of longint; i,j,k:longint; n,m,tot,tail,len,a,b,top,tt:longint; stt:ansistring; sum:int64;procedure sort(l,r:longint);var i,j,a,b:longint;begin i:=l; j:=r; a:=pos[z[(l+r)div 2]]; repeat while pos[z[i]]<a do inc(i); while a<pos[z[j]] do dec(j); if not (i>j) then begin b:=z[i]; z[i]:=z[j]; z[j]:=b; inc(i); dec(j); end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r);end;procedure sort1(l,r:longint);var i,j,a,b:longint;begin i:=l; j:=r; a:=pos[clear[(l+r)div 2]]; repeat while pos[clear[i]]<a do inc(i); while a<pos[clear[j]] do dec(j); if not (i>j) then begin b:=clear[i]; clear[i]:=clear[j]; clear[j]:=b; inc(i); dec(j); end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r);end;procedure insert(a:longint);var p,np,q,nq:longint;begin inc(tot); np:=tot; p:=tail; x[np].len:=x[p].len+1; x[np].key:=1; while (p<>0)and(x[p].tranc[a]=0) do begin x[p].tranc[a]:=np; p:=x[p].fa; end; if x[p].tranc[a]=0 then x[p].tranc[a]:=np else begin q:=x[p].tranc[a]; if x[q].len=x[p].len+1 then x[np].fa:=q else begin inc(tot); nq:=tot; x[nq]:=x[q]; x[nq].key:=0; x[nq].len:=x[p].len+1; x[q].fa:=nq; x[np].fa:=nq; while (x[p].tranc[a]=q) do begin x[p].tranc[a]:=nq; p:=x[p].fa; end; end; end; tail:=np;end;procedure init(a,b:longint);begin w[len,1]:=b; if w[a,2]=0 then w[a,2]:=len else w[w[a,1],2]:=len; w[a,1]:=len; inc(len);end;procedure dfs(a:longint);var tt:longint;begin tt:=w[a,2]; inc(len); pos[a]:=len; if x[a].key=1 then y[n-x[a].len+1]:=a; while tt<>0 do begin dep[w[tt,1]]:=dep[a]+1; dfs(w[tt,1]); tt:=w[tt,2]; end;end;function lca(a,b:longint):longint;var i:longint;begin if dep[a]<dep[b] then begin i:=a; a:=b; b:=i; end; for i:=20 downto 0 do if dep[st[a,i]]>=dep[b] then a:=st[a,i]; if a=b then exit(a); for i:=20 downto 0 do if st[a,i]<>st[b,i] then begin a:=st[a,i]; b:=st[b,i]; end; exit(st[a,0]);end;procedure solve(a:longint);var tt:longint;begin tt:=w[a,2]; while tt<>0 do begin solve(w[tt,1]); size[a]:=size[a]+size[w[tt,1]]; tt:=w[tt,2]; end; sum:=sum+(int64(x[a].len-x[x[a].fa].len)*(size[a]-1)*(size[a]))div 2;end;begin readln(n,m); readln(stt); tot:=0; tail:=0; for i:=n downto 1 do insert(ord(stt[i])-96); len:=tot+1; for i:=1 to tot do begin init(x[i].fa,i); st[i,0]:=x[i].fa; end; len:=0; dep[0]:=1; dfs(0); for j:=1 to 20 do for i:=1 to tot do st[i,j]:=st[st[i,j-1],j-1]; fillchar(size,sizeof(size),0); for i:=1 to m do begin read(a); sum:=0; clear[0]:=1; clear[1]:=0; for j:=1 to a do begin read(z[j]); size[y[z[j]]]:=1; z[j]:=y[z[j]]; end; sort(1,a); top:=1; t[top]:=0; for j:=1 to a do begin if z[j]=z[j-1] then continue; tt:=lca(z[j],t[top]); while dep[t[top]]>dep[tt] do begin if dep[t[top-1]]<=dep[tt] then begin fa[t[top]]:=tt; size[tt]:=size[tt]+size[t[top]]; dec(top); if t[top]<>tt then begin inc(top); t[top]:=tt; inc(clear[0]); clear[clear[0]]:=tt; end; break; end; fa[t[top]]:=t[top-1]; size[t[top-1]]:=size[t[top-1]]+size[t[top]]; dec(top); end; inc(top); t[top]:=z[j]; inc(clear[0]); clear[clear[0]]:=z[j]; end; while top>1 do begin fa[t[top]]:=t[top-1]; size[t[top-1]]:=size[t[top-1]]+size[t[top]]; dec(top); end; sum:=0; for j:=1 to clear[0] do sum:=sum+(int64(x[clear[j]].len-x[fa[clear[j]]].len)*(size[clear[j]]-1)*size[clear[j]])div 2; writeln(sum); for j:=1 to clear[0] do begin size[clear[j]]:=0; fa[clear[j]]:=0; end; end;end.
0 0
- [BZOJ3879] SvT
- [bzoj3879]SvT
- BZOJ3879 SvT
- bzoj3879 SvT
- bzoj3879: SvT 后缀自动机
- 【BZOJ3879】SvT 后缀树+虚树
- BZOJ3879: SvT 后缀树 虚树
- [BZOJ3879]SvT(后缀数组+单调栈)
- BZOJ3879:SvT(后缀自动机+虚树)
- bzoj3879 SvT(后缀数组+单调栈)
- 【BZOJ3879】SvT,后缀数组+单调栈维护sum
- bzoj3879
- SVT
- 3879: SvT
- bzoj 3879 SvT
- bzoj 3879: SvT
- 矩阵填充的SVT算法
- UT-IT-ST-BBIT-SDV-SIT-SVT
- 什么是公有云和私有云
- 新学期,新起点,新计划;
- C++语言
- some frequently-used formula
- gitHub上传本地代码
- [BZOJ3879] SvT
- 4.redis分片
- 九度题目1434
- Leetcode283 Move Zeros
- 关于notepad++和gcc绑定
- jdbc连接oracle的方法
- Stanford 机器学习笔记 Week6 Advice for Applying Machine Learning
- 三层初体验
- 搭建博客hexo