题目

如果是\(hash\)做法的话显然就是把每一个位置后面的\(k\)个位置的hash值拿出来做一个莫队板子就好了

考虑一下牛逼的\(SAM\)

我们完全可以构造出来一棵后缀树,对于每个点找到其祖先里深度最小且\(len<=k\)的一个点,我们莫队一下就好了

最优分块大小是\(\frac{n}{\sqrt{m}}\),这样复杂度是\(O(n\sqrt{m})\)

代码

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #define re register
  7. #define LL long long
  8. #define max(a,b) ((a)>(b)?(a):(b))
  9. #define min(a,b) ((a)<(b)?(a):(b))
  10. inline int read() {
  11. char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
  12. while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
  13. }
  14. const int maxn=6000005;
  15. struct Ask{int l,r,rk;}q[100005];
  16. int n,m,k,lst=1,cnt=1;LL ans;
  17. char S[maxn>>1];
  18. int g[maxn],h[maxn],son[maxn][7],len[maxn],pos[maxn>>1],fa[maxn],tmp[maxn];
  19. int tax[maxn>>1],A[maxn],id[maxn>>1];LL Ans[100005];
  20. inline void ins(int c,int o) {
  21. int p=++cnt,f=lst;lst=p;
  22. len[p]=len[f]+1,pos[o]=p;
  23. while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
  24. if(!f) {fa[p]=1;return;}
  25. int x=son[f][c];
  26. if(len[f]+1==len[x]) {fa[p]=x;return;}
  27. int y=++cnt;
  28. len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
  29. for(re int i=0;i<7;i++) son[y][i]=son[x][i];
  30. while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
  31. }
  32. inline int chk(char x) {
  33. if(x=='f') return 0;if(x=='z') return 1;
  34. if(x=='o') return 2;if(x=='u') return 3;
  35. if(x=='t') return 4;if(x=='s') return 5;
  36. return 6;
  37. }
  38. inline void add(int x) {
  39. if(!h[pos[x]]) return;
  40. ans+=tmp[h[pos[x]]];++tmp[h[pos[x]]];
  41. }
  42. inline void del(int x) {
  43. if(!h[pos[x]]) return;
  44. --tmp[h[pos[x]]];ans-=tmp[h[pos[x]]];
  45. }
  46. inline int cmp(Ask A,Ask B) {return id[A.l]==id[B.l]?A.r<B.r:id[A.l]<id[B.l];}
  47. int main() {
  48. n=read(),m=read(),k=read();scanf("%s",S+1);
  49. for(re int i=1;i<=n;i++) S[i]=chk(S[i]);
  50. for(re int i=n;i;--i) ins(S[i],i);
  51. for(re int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].rk=i;
  52. int sz=n/(std::sqrt(m)+1);int L=1,tot=1;
  53. while(L<=n) {for(re int i=L;i<=min(L+sz-1,n);i++) id[i]=tot;L+=sz,++tot;}
  54. std::sort(q+1,q+m+1,cmp);
  55. for(re int i=2;i<=cnt;i++) if(len[i]>=k&&len[fa[i]]<k) g[i]=1;
  56. for(re int i=1;i<=cnt;i++) tax[len[i]]++;
  57. for(re int i=1;i<=n;i++) tax[i]+=tax[i-1];
  58. for(re int i=cnt;i;--i) A[tax[len[i]]--]=i;
  59. for(re int i=1;i<=cnt;i++) {
  60. int x=A[i];
  61. if(g[x]) h[x]=x;else h[x]=h[fa[x]];
  62. }
  63. int l=0,r=0;
  64. for(re int i=1;i<=m;i++) {
  65. while(r<q[i].r) add(++r);
  66. while(l<q[i].l) del(l++);
  67. while(l>q[i].l) add(--l);
  68. while(r>q[i].r) del(r--);
  69. Ans[q[i].rk]=ans;
  70. }
  71. for(re int i=1;i<=m;i++) printf("%lld\n",Ans[i]);
  72. return 0;
  73. }

【LGP5112】FZOUTSY的更多相关文章

  1. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  2. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  3. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  5. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  6. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  7. Python高手之路【一】初识python

    Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...

  8. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  9. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

随机推荐

  1. linux 系统优化,调优

    1.系统安装前的规则 a.分区:不同环境不同分法,按自己的需求来 以硬盘500G为例 /boot 100M-200M(只存放grub和启动相关文件,不存放其他) /  80G-100G (因为很多人默 ...

  2. Python学习笔记(五)——异常处理

    Python 异常总结 异常名称 解释 AssertionError 断言语句(assert)失败:当assert关键字后边的条件为假时,程序将抛出该异常,一般用于在代码中置入检查点 OSError ...

  3. Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.android.support:appcompat-v7:26.1.0

    android studio  3.0 出现此问题可能是因为 你的android studio 时脱机状态 无法下载资源 这时候你可以点击左上角分File->Other Settings-> ...

  4. Sqlite多线程相关整理

    Sqlite多线程相关整理 Sqlite With MultiThreads 什么是线程安全? 当多个线程访问某个方法时,不管你通过怎样的调用方式.或者说这些线程如何交替地执行,我们在主程序中不需要去 ...

  5. C# - Finalize 和 Dispose

    重要: https://www.cnblogs.com/Jessy/articles/2552839.html https://blog.csdn.net/daxia666/article/detai ...

  6. js面试总结3

    异步和单线程 题目: 1.同步和异步的区别? 2.一个关于setTimeout的笔试题. 3.前段使用异步的场景有哪些? 什么是异步? console.log(100) setTimeout(func ...

  7. 2018-2019-2 20175323 实验一《Java开发环境的熟悉》实验报告

    java开发环境的熟悉-1 java开发环境的熟悉-2 下载IDEA和破解的过程我参考了https://blog.csdn.net/shengshengshiwo/article/details/79 ...

  8. css选择器之间的 空格和逗号

    当两个选择器之间有空格的情况下,代表的是子类选择器 .a .b{} 代表的是a类的b子类 而两个选择器之间没有空格的情况下,代表的是同时拥有两个类名的标签 <div class="a ...

  9. 阿里云CentOs7上安装Tomcat

    一.下载安装tomcat8 cd /usr/ #创建tomcat目录 mkdir tomcat #从网上download 压缩包 wget tomcat8 url #解压 tar -zxvf apac ...

  10. 01_MyBatis入门

    一.MyBaits介绍 1.MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且 ...