题解

\(SAM+set\)启发式合并+扫描线

首先可以发现题目要求的就是查询结尾在一段区间内的\(LCS\)

这个显然就是\(SAM\)的\(parent\)树上的\(step[LCA]\)

我们可以对后缀自动机的每个节点\(u\)开一个\(set\)来维护\(endpos\)集合

然后对\(u\)的儿子的\(right\)集合启发式合并,\(u\)的儿子和\(u\)当前集合内的点的\(LCS\)就是\(step[u]\)

显然在贡献是相同的情况下距离越近的越有效

所以我们对于要合并的点的一个位置\(u\)只需要找这个位置的前驱和后继并加入点对即可

这样我们处理出了若干个\((x,y,v)\)的点对

那么对于一个询问\(l,r\)

有贡献的点对就是\(l\le x , r > y\)

所以我们就把所有的点对和询问按照右端点排序

每扫到一个点对\((x,y,v)\)

就把\(x\)位置加上\(v\)

查询就是查\(l\)位置之前的最大值

代码

  1. #include<set>
  2. #include<queue>
  3. #include<vector>
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<iostream>
  7. #include<algorithm>
  8. const int M = 400005 ;
  9. using namespace std ;
  10. inline int read() {
  11. char c = getchar() ; int x = 0 , w = 1 ;
  12. while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
  13. while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
  14. return x*w ;
  15. }
  16. char s[M] ;
  17. int n , m , tot ;
  18. int Last , cnt ;
  19. int fa[M] , st[M] , son[M][2] ;
  20. int b[M] , c[M] , ans[M] ;
  21. multiset < int > S[M] ;
  22. struct Q {
  23. int l , r , idx ;
  24. } q[M] ;
  25. struct Node {
  26. int x , y , v ;
  27. Node () { } ;
  28. Node (int Tx , int Ty , int Tv) {
  29. x = Tx , y = Ty , v = Tv ;
  30. if(x > y) swap(x , y) ;
  31. }
  32. } pi[M * 10] ;
  33. inline bool operator < (Q A , Q B) {
  34. return A.r < B.r ;
  35. }
  36. inline bool operator < (Node A , Node B) {
  37. return A.y < B.y ;
  38. }
  39. inline void Insert(int c) {
  40. int np = ++ cnt , p = Last ; Last = np ; st[np] = st[p] + 1 ;
  41. while(p && !son[p][c]) son[p][c] = np , p = fa[p] ;
  42. if(!p) fa[np] = 1 ;
  43. else {
  44. int q = son[p][c] ;
  45. if(st[q] == st[p] + 1) fa[np] = q ;
  46. else {
  47. int nq = ++ cnt ; st[nq] = st[p] + 1 ;
  48. memcpy(son[nq] , son[q] , sizeof(son[q])) ;
  49. fa[nq] = fa[q] ; fa[q] = fa[np] = nq ;
  50. while(p && son[p][c] == q) son[p][c] = nq , p = fa[p] ;
  51. }
  52. }
  53. }
  54. struct BIT {
  55. int c[M] ;
  56. inline int lowbit(int k) { return (k & (-k)) ; }
  57. inline void change(int k , int x) { while(k) c[k] = max(c[k] , x) , k -= lowbit(k) ; }
  58. inline int query(int k) { int ret = 0 ; while(k <= n) ret = max( ret , c[k] ) , k += lowbit(k) ; return ret ; }
  59. } T ;
  60. inline void Solve() {
  61. int lst = 1 ;
  62. for(int i = 1 ; i <= m ; i ++) {
  63. for(int j = lst ; j <= tot ; j ++) {
  64. if(q[i].r >= pi[j].y) {
  65. T.change(pi[j].x , pi[j].v) ;
  66. lst = j + 1 ;
  67. }
  68. else break ;
  69. }
  70. ans[q[i].idx] = T.query(q[i].l) ;
  71. }
  72. }
  73. int main() {
  74. n = read() ; m = read() ;
  75. scanf("%s",s + 1) ; Last = cnt = 1 ;
  76. for(int i = 1 ; i <= n ; i ++) {
  77. Insert(s[i] - '0') ;
  78. S[Last].insert(i) ;
  79. }
  80. for(int i = 1 ; i <= cnt ; i ++) ++ c[st[i]] ;
  81. for(int i = 1 ; i <= n ; i ++) c[i] += c[i - 1] ;
  82. for(int i = cnt ; i >= 1 ; i --) b[c[st[i]] --] = i ;
  83. for(int i = cnt , p ; i >= 1 ; i --) {
  84. p = b[i] ;
  85. if(!fa[p]) continue ;
  86. if(S[fa[p]].size() < S[p].size())
  87. swap(S[fa[p]] , S[p]) ;
  88. set < int >::iterator it , nw , pre , nxt ;
  89. for(it = S[p].begin() ; it != S[p].end() ; ++it) {
  90. S[fa[p]].insert(*it) ;
  91. nw = pre = nxt = S[fa[p]].find(*it) ; ++ nxt ;
  92. if(pre != S[fa[p]].begin()) -- pre , pi[++tot] = Node (*pre , *nw , st[fa[p]]) ;
  93. if(nxt != S[fa[p]].end()) pi[++tot] = Node (*nw , *nxt , st[fa[p]]) ;
  94. S[fa[p]].erase(*it) ;
  95. }
  96. for(it = S[p].begin() ; it != S[p].end() ; ++it)
  97. S[fa[p]].insert(*it) ;
  98. }
  99. for(int i = 1 ; i <= m ; i ++)
  100. q[i].idx = i , q[i].l = read() , q[i].r = read() ;
  101. sort(q + 1 , q + m + 1) ;
  102. sort(pi + 1 , pi + tot + 1) ;
  103. Solve() ;
  104. for(int i = 1 ; i <= m ; i ++)
  105. printf("%d\n",ans[i]) ;
  106. return 0 ;
  107. }

[LOJ6041雅礼集训2017]事情的相似度的更多相关文章

  1. 「雅礼集训 2017 Day7」事情的相似度

    「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...

  2. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  3. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  4. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

  5. [LOJ 6031]「雅礼集训 2017 Day1」字符串

    [LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...

  6. [LOJ 6030]「雅礼集训 2017 Day1」矩阵

    [LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...

  7. [LOJ 6029]「雅礼集训 2017 Day1」市场

    [LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...

  8. 【LYOI 212】「雅礼集训 2017 Day8」价(二分匹配+最大权闭合子图)

    「雅礼集训 2017 Day8」价 内存限制: 512 MiB时间限制: 1000 ms 输入文件: z.in输出文件: z.out   [分析] 蛤?一开始看错题了,但是也没有改,因为不会做. 一开 ...

  9. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

随机推荐

  1. Linux环境下如何查找哪个线程使用CPU最长

    top -H -p pid 查看端口是否被占用: netstat -apn|grep 80

  2. 写入文本文件时“\n”不是回车换行而是个方块“■”的解决方法

    用“\n”写入文本文件时,打开文本文件显示的为什么不是回车换行而是个黑方块“■”,但用file()读取时还是认为是一行一行的? 首先在WINDOWS里回车换行是"\r\n"; 而L ...

  3. Spring源码深度解析——笔记

    1.spring容器的基本用法 xml配置 <bean id="myTestBean" class="bean.MyTestBean"/> 调用 B ...

  4. Joomla中的Task 和view 深入学习

    [本文转自:梦溪笔记] Joomla 是一个优秀的CMS系统,她可以让你快速的完成一个网站的建设,她提供组件,模块,模板能够满足你大部分的网站需求.而组件在其中举足轻重. 一.基本知识 组件(comp ...

  5. php网站前台utf-8格式有时会出现莫名其妙的空白行,重新保存下编码格式就可以了

    php网站前台utf-8格式有时会出现莫名其妙的空白行,重新保存下编码格式就可以了.

  6. Windows下VMware虚拟机使用Centos,Docker方式安装openstf的小坑

    今天使用docker方式安装openstf碰到了一小坑,坑了我半天.特此记录! docker方式安装stf就不说了,网上教程一大把. 但是... 安装完之后.进入web控制界面,手机连接的好好的.但硕 ...

  7. Android设备adb授权的原理【转】

    本文转载自:http://blog.csdn.net/zahuopuboss/article/details/50831171 http://blog.csdn.net/sowhat_ah/artic ...

  8. POJ 2017 Speed Limit (直叙式的简单模拟 编程题目 动态属性很少,难度小)

                                                                                                      Sp ...

  9. POJ2135 Farm Tour —— 最小费用最大流

    题目链接:http://poj.org/problem?id=2135 Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  10. 以太坊EVM在安全性方面的考虑

    以太坊上用户编写的合约是不可控的,要保证这些合约能够正确执行并且不会影响区块链的稳定,虚拟机需要做安全方面的考虑. 1 在程序执行过程中采取的每个计算步骤都必须提前支付费用, 从而防止DoS攻击.先消 ...