题意:统计一段字符串中形如UVU的子串个数(其中V的长度固定为g)。

问题等价于求满足$g+1\leqslant |j-i|\leqslant g+LCP(i,j)$的后缀(i,j)的对数,即$\sum\limits_{i<j}[g+1\leqslant |j-i|\leqslant g+LCP(i,j)]$。

由于将原串反转后的后缀(i,j)的LCP等于其在原串的后缀自动机上对应结点的LCA的最大长度,可以枚举LCA,在fail树上将right数组启发式合并即可。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+,M=;
char s[N];
int n,fa[N],go[N][M],mxl[N],last,tot,g,ss[N],c[N],ka;
int rt[N],ls[N*],rs[N*],sum[N*],tot2,ans[N];
#define mid ((l+r)>>1)
int newnode2() {int u=++tot2; sum[u]=ls[u]=rs[u]=; return u;}
void upd(int& u,int p,int l=,int r=n-) {
if(!u)u=newnode2();
sum[u]++;
if(l==r)return;
p<=mid?upd(ls[u],p,l,mid):upd(rs[u],p,mid+,r);
}
void mg(int& u,int v) {
if(!u||!v) {u=u|v; return;}
sum[u]+=sum[v];
mg(ls[u],ls[v]),mg(rs[u],rs[v]);
}
int qry(int u,int L,int R,int l=,int r=n-) {
if(l>=L&&r<=R)return sum[u];
if(l>R||r<L)return ;
return qry(ls[u],L,R,l,mid)+qry(rs[u],L,R,mid+,r);
}
void dfs(int u,int v,int l=,int r=n-) {
if(!sum[v])return;
if(l==r) {
ans[u]+=qry(rt[u],l+(+g),l+(mxl[u]+g));
ans[u]+=qry(rt[u],l-(mxl[u]+g),l-(+g));
return;
}
dfs(u,ls[v],l,mid),dfs(u,rs[v],mid+,r);
}
int newnode(int l) {int u=++tot; rt[u]=ans[u]=,mxl[u]=l,memset(go[u],,sizeof go[u]); return u;}
void add(int ch,int r) {
int p=last,np=last=newnode(mxl[p]+);
upd(rt[np],r);
for(; p&&!go[p][ch]; p=fa[p])go[p][ch]=np;
if(!p)fa[np]=;
else {
int q=go[p][ch];
if(mxl[q]==mxl[p]+)fa[np]=q;
else {
int nq=newnode(mxl[p]+);
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for(; p&&go[p][ch]==q; p=fa[p])go[p][ch]=nq;
}
}
}
void solve() {
for(int i=; i<=tot; ++i)c[i]=;
for(int i=; i<=tot; ++i)++c[mxl[i]];
for(int i=; i<=tot; ++i)c[i]+=c[i-];
for(int i=; i<=tot; ++i)ss[--c[mxl[i]]]=i;
for(int i=tot-; i>=; --i) {
int v=ss[i],u=fa[v];
if(!u)continue;
if(sum[rt[v]]>sum[rt[u]])swap(rt[u],rt[v]);
dfs(u,rt[v]),mg(rt[u],rt[v]);
ans[u]+=ans[v];
}
}
int main() {
int T;
for(scanf("%d",&T); T--;) {
scanf("%d%s",&g,s),n=strlen(s);
tot=tot2=,last=newnode();
for(int i=; i<n; ++i)add(s[i]-'a',i);
solve();
printf("Case %d: %d\n",++ka,ans[]);
}
return ;
}

UVA - 10829 L-Gap Substrings (后缀自动机+线段树启发式合并)的更多相关文章

  1. Bzoj2534:后缀自动机 主席树启发式合并

    国际惯例的题面:考虑我们求解出字符串uvu第一个u的右端点为i,第二个u的右端点为j,我们需要满足什么性质?显然j>i+L,因为我们选择的串不能是空串.另外考虑i和j的最长公共前缀(也就是说其p ...

  2. BZOJ3413: 匹配(后缀自动机 线段树合并)

    题意 题目链接 Sol 神仙题Orz 后缀自动机 + 线段树合并... 首先可以转化一下模型(想不到qwq):问题可以转化为统计\(B\)中每个前缀在\(A\)中出现的次数.(画一画就出来了) 然后直 ...

  3. cf666E. Forensic Examination(广义后缀自动机 线段树合并)

    题意 题目链接 Sol 神仙题Orz 后缀自动机 + 线段树合并 首先对所有的\(t_i\)建个广义后缀自动机,这样可以得到所有子串信息. 考虑把询问离线,然后把\(S\)拿到自动机上跑,同时维护一下 ...

  4. 洛谷P2178 [NOI2015]品酒大会(后缀自动机 线段树)

    题意 题目链接 Sol 说一个后缀自动机+线段树的无脑做法 首先建出SAM,然后对parent树进行dp,维护最大次大值,最小次小值 显然一个串能更新答案的区间是\([len_{fa_{x}} + 1 ...

  5. BZOJ1396: 识别子串(后缀自动机 线段树)

    题意 题目链接 Sol 后缀自动机+线段树 还是考虑通过每个前缀的后缀更新答案,首先出现次数只有一次,说明只有\(right\)集合大小为\(1\)的状态能对答案产生影响 设其结束位置为\(t\),代 ...

  6. [Luogu5161]WD与数列(后缀数组/后缀自动机+线段树合并)

    https://blog.csdn.net/WAautomaton/article/details/85057257 解法一:后缀数组 显然将原数组差分后答案就是所有不相交不相邻重复子串个数+n*(n ...

  7. 洛谷P4493 [HAOI2018]字串覆盖(后缀自动机+线段树+倍增)

    题面 传送门 题解 字符串就硬是要和数据结构结合在一起么--\(loj\)上\(rk1\)好像码了\(10k\)的样子-- 我们设\(L=r-l+1\) 首先可以发现对于\(T\)串一定是从左到右,能 ...

  8. 模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)

    模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...

  9. 【BZOJ4556】[TJOI2016&HEOI2016] 字符串(后缀自动机+线段树合并+二分)

    点此看题面 大致题意: 给你一个字符串\(s\),每次问你一个子串\(s[a..b]\)的所有子串和\(s[c..d]\)的最长公共前缀. 二分 首先我们可以发现一个简单性质,即要求最长公共前缀,则我 ...

随机推荐

  1. 山东省第十届ACM省赛参赛后的学期总结

    5.11,5.12两天的济南之旅结束了,我也参加了人生中第一次正式的acm比赛,虽然是以友情队的身份,但是我依旧十分兴奋. 其实一直想写博客来增加自己的能力的,但是一直拖到现在,正赶上老师要求写一份总 ...

  2. CNN卷积汇总

    1,卷积作用:减少参数(卷积核参数共享),卷积过程中不断对上一个输出进行抽象,由局部特征归纳为全局特征(不同卷积层可视化可以观察到这点) 2,卷积核 早期卷积核由人工总结,如图像处理中有: 深度神经网 ...

  3. 在 Windows 10 上用超级终端配置 Cisco 3560 Series

    在Cisco实验中,恢复路由器出厂配置是必须的内容,所以今天就由小编来为大家介绍Cisco软件怎么恢复路由器出厂配置. 1. 通过终端连接交换机1.1. 通过 Windows 的超级终端连接 Cisc ...

  4. WebMvcConfigurationSupport与WebMvcConfigurer的关系

    大家从网上及源码注释上查到的解释是,在spring中配置WebMvc时有两种方法,一种是继承WebMvcConfigurationSupport,重写里面相应的方法,还有一种是继承WebMvcConf ...

  5. MySQL中关于主从数据库同步延迟的问题解决

    MySQL的主从同步是一个很成熟的架构,优点为:①在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;②在从主服务器进行备份,避免备份期间影响主服务器服务;③当主服务器出现问题时,可以 ...

  6. Storm本地启动拓扑报错:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/storm/topology/IRichSpout

    问题描述: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/storm/topology ...

  7. spring请求多方式

    <!-- 使表单可以使用GET,.POST. HEAD.OPTIONS.PUT.DELETE.TRACE方式提交--> <filter> <filter-name> ...

  8. git diff 命令介绍

    https://www.jianshu.com/p/6e1f7198e76a https://www.jianshu.com/p/5b6a014ac3db https://blog.csdn.net/ ...

  9. 移动端、pc端通用点击复制

    点击复制 function copyArticle(event){ const range = document.createRange(); range.selectNode(document.ge ...

  10. DockerFile 编译语法详解

    Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像,本小结首先介绍Dockerfile典型的基本结构和它支持的众多指令,并具体讲解通过这些指令来编写定 ...