题目描述

有一种形如uvu形式的字符串,其中u是非空字符串,且V的长度正好为L,那么称这个字符串为L-Gap字符串
给出一个字符串S,以及一个正整数L,问S中有多少个L-Gap子串.

L≤10 字符串长≤50000

分析

这道题难度挺大的。。。
考虑一个合法的UVU串。假设两个U结束位置分别是i,j(i < j)。
设两个前缀i,j的最长公共后缀长度为len。那么i,j合法时满足以下两个条件:
1. i+L < j
2. i+L+len≥j

现在考虑给字符串建后缀自动机,然后对于两个前缀,分别是i和j,在sam上跑到两个不同节点,这两个节点在fail树上lca所表示最长后缀的长度就是i,j的最长公共后缀了。
那么一个解法就出来了:用平衡树维护一棵子树所有的前缀,递归完所有儿子后,每个平衡树两两合并,并且合并前其中一棵子树的所有前缀拿出来到另一个平衡树上查询。用启发式合并即可做到O(nlog2n)O(nlog^2n)
我用的是treap

#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int N=50005,M=N*2;typedef long long LL;int n,m,L,tot,last,e[M][256],step[M],fail[M],h[M],E[M],nxt[M],root[M],son[N][2],fix[N],key[N],size[N],fa[N],D[N];LL ans;char s[N];void Extend(int c)
{int np=++m,p=last,q,nq;last=np;step[np]=step[p]+1;for (;p>=0 && !e[p][c];p=fail[p]) e[p][c]=np;if (p<0) fail[np]=0;else{q=e[p][c];if (step[p]==step[q]-1) fail[np]=q;else{nq=++m;fail[nq]=fail[q]; memcpy(e[nq],e[q],sizeof(e[q]));step[nq]=step[p]+1;fail[np]=fail[q]=nq;for (;p>=0 && e[p][c]==q;p=fail[p]) e[p][c]=nq;}}
}void add(int x,int y)
{E[++tot]=y; nxt[tot]=h[x]; h[x]=tot;
}void calc(int x,int y,int sig)
{if (!x) return;if (key[x]>y) calc(son[x][0],y,sig);else{ans+=sig*size[son[x][0]]+sig;if (key[x]<y) calc(son[x][1],y,sig);}
}void Rotate(int x,int t)
{int y=fa[x];fa[x]=fa[y];if (fa[y]>0){if (son[fa[y]][0]==y) son[fa[y]][0]=x;else son[fa[y]][1]=x;}son[y][t]=son[x][t^1];if (son[y][t]>=0) fa[son[y][t]]=y;son[x][t^1]=y;fa[y]=x;size[y]=size[son[y][0]]+size[son[y][1]]+1;size[x]=size[son[x][0]]+size[son[x][1]]+1;
}void insert(int x,int y)
{size[x]++;if (key[y]<key[x]){if (son[x][0]){insert(son[x][0],y);if (fix[x]>fix[son[x][0]]) Rotate(son[x][0],0);}else{son[x][0]=y; fa[y]=x;son[y][0]=son[y][1]=0;size[y]=1;if (fix[x]>fix[y]) Rotate(y,0);}}else{if (son[x][1]){insert(son[x][1],y);if (fix[x]>fix[son[x][1]]) Rotate(son[x][1],1);}else{son[x][1]=y; fa[y]=x;son[y][0]=son[y][1]=0;size[y]=1;if (fix[x]>fix[y]) Rotate(y,1);}}
}void dfs(int x)
{for (int i=h[x];i;i=nxt[i]){dfs(E[i]);if (!root[x]) root[x]=root[E[i]];else if (root[E[i]]){if (size[root[x]]<size[root[E[i]]]) root[x]^=root[E[i]]^=root[x]^=root[E[i]];D[tot=1]=root[E[i]];for (int j=1;j<=tot;j++){int k=D[j];if (son[k][0]) D[++tot]=son[k][0];if (son[k][1]) D[++tot]=son[k][1];k=key[k];calc(root[x],k+L+step[x],1); calc(root[x],k+L,-1);calc(root[x],k-L-1,1); calc(root[x],k-L-step[x]-1,-1);}for (int j=1;j<=tot;j++){insert(root[x],D[j]);if (fa[D[j]]==0) root[x]=D[j];}}}
}int main()
{srand(65870762);scanf("%d%s",&L,s+1);fail[0]=-1;n=strlen(s+1);for (int i=1;i<=n;i++) Extend(s[i]);for (int i=1;i<=m;i++) add(fail[i],i);tot=0;for (int i=1,j=0;i<=n;i++){for (;j>0 && e[j][s[i]]==0;j=fail[j]);if (e[j][s[i]]>0){j=e[j][s[i]];root[j]=++tot;key[tot]=i;fix[tot]=rand()*109+rand();size[tot]=1;}}dfs(0);printf("%lld\n",ans);return 0;
}

[bzoj2534]Uva10829L-gap字符串相关推荐

  1. 多线程抢票_java多线程下模拟抢票

    我们设置三个对象分别同时抢20张票,利用多线程实现. public class Web123506 implements Runnable{ private int ticteksNums=20;// ...

  2. 【做题】BZOJ2534 L-gap字符串——调和级数

    题意:给出一个字符串,问其中有多少个子串恰好为\(uvu\)的形式.其中,\(u\)非空,\(v\)的长度恰好为\(l\). \(n \leq 5 \times 10^4\) 我们设两个后缀的起点分别 ...

  3. bzoj2534 Uva10829L-gap字符串(SA+lcp同bzoj2119)

    求形如ABA的子串个数,同bzoj2119,题解看这里 tips:没说全是小写字母你就别换成int了...无谓的WA三发 #include <cstdio> #include <cs ...

  4. Binary Gap(二进制空白)

    中文标题[二进制空白] 英文描述 A binary gap within a positive integer N is any maximal sequence of consecutive zer ...

  5. Java实现List中某个对象属性中的字符串参数首字母进行排序

    public static void main(String[] args) {//数组 中文首字母排序// Collator 类是用来执行区分语言环境的 String 比较的,这里选择使用CHINA ...

  6. 怎么判断一个字符串的最长回文子串是否在头尾_最长回文字串/子序列问题(leetcode5,9,519)

    leetcode 5 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: " ...

  7. decimal类型 go_Go 语言程序设计——字符串类型(2)

    格式化布尔值 布尔值使用 %t (真值) 格式指令来输出 例子: package main import ( "fmt" ) func IntForBool (b bool) in ...

  8. C语言字符串操作函数 - strcpy、strcmp、strcat、反转、回文

    C语言字符串操作函数 1. 字符串反转 - strRev 2. 字符串复制 - strcpy 3. 字符串转化为整数 - atoi 4. 字符串求长 - strlen 5. 字符串连接 - strca ...

  9. 八、Mysql 间隙锁(gap 锁)与慢查询

    Mysql 间隙锁(gap 锁)与慢查询 gap锁与慢查询 gap锁 事务语法 开启事务 事务回滚 事务提交 还原点(演示) 业务设计 逻辑设计 范式设计 查询测试 反范式设计 总结 范式化设计优缺点 ...

最新文章

  1. 乱谈管理(优秀部门经理的职业素质)
  2. python中plot实现即时数据动态显示方法_python中plot实现即时数据动态显示方法
  3. [译] 使用 Web3 和 Vue.js 来创建你的第一个以太坊 dAPP(第二部分)
  4. 巴巴运动网学习笔记(36-40)
  5. 使用.Net 1.1的项目,TreeView控件不能正常显示
  6. VC2010运行C程序时黑框一闪就没
  7. 如何将Webpack与React结合使用:深入的教程
  8. Keepalived实现双机热备
  9. 知识图谱-远程监督关系提取
  10. JavaScript学习(二十五)—实现无缝滚动
  11. 这大概是今年最值得推荐的“数据分析工具”
  12. PIE SDK矢量数据的读取
  13. 关于/r与/n以及 /r/n 的区别总结
  14. IE缓存文件提取器 视频,音频,图片一网打尽
  15. 对外汉语语料库有哪些_燃,9大对外汉语必备语料库,每个都很有“性格”!!...
  16. java数据结构银行叫号_数据结构C语言版利用队列结构实现银行叫号系统要..._结构工程师_帮考网...
  17. 通篇详解-CMMM智能制造能力成熟度
  18. 强化学习的A3C算法应用(训练Atari游戏)
  19. CSAPP 第三版 第四章 家庭作业and so on
  20. visual studio 错误:在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include StdAfx.h”?

热门文章

  1. 同济大学计算机考研资料汇总
  2. 基于SpringBoot+MyBatis 五子棋双人对战
  3. 熟悉计算机信息处理的基础知识,信息处理技术员学习指导—考试内容
  4. 企业决策智能项目的五种失败姿势
  5. 现代信号分析与处理简答题期末总结BISTU
  6. 外汇天眼:英镑暴跌英国国债暴跌 英国新政府宣布激进的减税促经济计划
  7. 尚学堂 高琪JAVA300集第十一章作业 编程题答案
  8. Android 新浪微博客户端
  9. python numpy库作用_python数据分析之numpy库
  10. ZooKeeper三种安装模式