题意

题目链接

Sol

这题打死我也不会想到后缀数组的,应该会全程想AC自动机之类的吧

但知道这题能用后缀数组做之后应该就不是那么难了

首先把\(S\)和\(S0\)拼到一起跑,求出Height数组

暴力枚举每个后缀是否能成为答案。

具体来说,每次比较当前后缀和\(S_0\)的lcp,如果长度\(< N\)的话就从不合法的位置继续匹配

rmq维护一下区间lcp最小值

BZOJ上被完美卡常

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. const int MAXN = 2e5 + 10;
  5. const int INF = 2333;
  6. inline int read() {
  7. char c = getchar(); int x = 0, f = 1;
  8. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  9. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  10. return x * f;
  11. }
  12. int N, M, L, rak[MAXN], tax[MAXN], tp[MAXN], sa[MAXN], H[MAXN], f[MAXN][20], lg2[MAXN];
  13. char s[MAXN], s0[MAXN];
  14. void Qsort() {
  15. for(int i = 0; i <= M; i++) tax[i] = 0;
  16. for(int i = 1; i <= N; i++) tax[rak[i]]++;
  17. for(int i = 1; i <= M; i++) tax[i] += tax[i - 1];
  18. for(int i = N; i >= 1; i--) sa[tax[rak[tp[i]]]--] = tp[i];
  19. }
  20. void SuffixSort() {
  21. for(int i = 1; i <= N; i++) rak[i] = s[i], tp[i] = i; M = 233; Qsort();
  22. for(int w = 1, p = 0; p < N; w <<= 1, M = p) { p = 0;
  23. for(int i = 1; i <= w; i++) tp[++p] = N - i + 1;
  24. for(int i = 1; i <= N; i++) if(sa[i] > w) tp[++p] = sa[i] - w;
  25. Qsort(); swap(tp, rak); rak[sa[1]] = p = 1;
  26. for(int i = 2; i <= N; i++) rak[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + w] == tp[sa[i - 1] + w]) ? p : ++p;
  27. }
  28. for(int i = 1, k = 0; i <= N; i++) {
  29. if(k) k--; int j = sa[rak[i] - 1];
  30. while(s[i + k] == s[j + k]) k++;
  31. H[rak[i]] = k;
  32. }
  33. }
  34. void Pre() {
  35. for(int i = 1; i <= N; i++) f[i][0] = H[i];
  36. for(int j = 1; j <= 17; j++)
  37. for(int i = 1; i + (1 << j) - 1 <= N; i++) f[i][j] = min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
  38. }
  39. int Query(int x, int y) {
  40. if(x > y) swap(x, y); x++;
  41. int k = lg2[y - x + 1];
  42. return min(f[x][k], f[y - (1 << k) + 1][k]);
  43. }
  44. int check(int x, int y, int dep) {
  45. if(dep == 3) return Query(rak[x], rak[y]);
  46. int num = Query(rak[x], rak[y]);
  47. num += check(x + num + 1, y + num + 1, dep + 1) + 1;
  48. return num;
  49. }
  50. void solve() {
  51. scanf("%s%s", s + 1, s0 + 1);
  52. L = strlen(s0 + 1); N = strlen(s + 1);
  53. for(int i = 1; i <= L; i++) s[N + i] = s0[i];
  54. N += L;
  55. SuffixSort(); Pre(); N -= L; int ans = 0;
  56. for(int i = 1; i <= N - L + 1; i++) if(check(i, N + 1, 0) >= L) ans++;
  57. printf("%d\n", ans);
  58. }
  59. int main() {
  60. //freopen("a.in", "r", stdin);
  61. lg2[1] = 0; for(int i = 2; i <= MAXN - 1; i++) lg2[i] = lg2[i >> 1] + 1;
  62. for(int T = read(); T; solve(), T--);
  63. return 0;
  64. }
  65. /*
  66. 2
  67. ATCGCCCTA
  68. CTTCA
  69. ATCGCCCTA
  70. CTTCA
  71. */

洛谷P3763 [TJOI2017]DNA(后缀数组 RMQ)的更多相关文章

  1. 洛谷P3763 [Tjoi2017]DNA 【后缀数组】

    题目链接 洛谷P3763 题解 后缀数组裸题 在BZOJ被卡常到哭QAQ #include<algorithm> #include<iostream> #include< ...

  2. [洛谷P3763] [TJOI2017]DNA

    洛谷题目链接:[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其 ...

  3. 洛谷P3763 [TJOI2017]DNA(后缀自动机)

    传送门 好像用SAM写的很少诶…… 其实我一开始也没想到要用SAM的……主要是没有想到找的时候可以dfs…… 首先建一个SAM,然后跑一遍dfs,枚举一下下一位,如果相同直接继续,否则就花费一次次数来 ...

  4. [TJOI2017] DNA - 后缀数组,稀疏表

    [TJOI2017] DNA Description 求模式串与主串的匹配次数,容错不超过三个字符. Solution 枚举每个开始位置,进行暴力匹配,直到失配次数用光或者匹配成功.考虑到容错量很小, ...

  5. [TJOI2017]DNA --- 后缀数组

    [TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S, 有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个 ...

  6. [BZOJ4892][TJOI2017]DNA(后缀数组)

    题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状 ...

  7. 洛谷-P3809-后缀排序(后缀数组)

    看了求后缀数组的倍增法之后很快就理解了,但是自己写的倍增法用map排序还是超时了.然后看了两天别人写的模板,题目是通过了,但感觉代码还是半懂半背的.以后多熟悉熟悉吧: 后缀数组 #include &q ...

  8. 洛谷 P4143 采集矿石 后缀数组

    题目背景 ZRQ 成功从坍塌的洞穴中逃了出来.终于,他看到了要研究的矿石.他想挑一些带回去完成任务. 题目来源:Zhang_RQ哦对了 \(ZRQ\) 就他,嗯 题目描述 ZRQ 发现这里有 \(N\ ...

  9. 洛谷3809 SA模板 后缀数组学习笔记(复习)

    其实SA这个东西很久之前就听过qwq 但是基本已经忘的差不多了 嘤嘤嘤 QWQ感觉自己不是很理解啊 所以写不出来那种博客 QWQ只能安利一些别人的博客了 小老板 真的是讲的非常好 不要在意名字 orz ...

随机推荐

  1. web站点启用https (一)

    HTTPS技术是现在主流网站都采用的安全加密传输数据的技术,本篇文档将分为2部分讲解PKI的基本原理及在web站点配置https访问. 一.理论知识 1.PKI(public key infrastr ...

  2. 线索二叉树的理解和实现(Java)

    线索二叉树的基本概念 我们按某种方式对二叉树进行遍历,将二叉树中所有节点排序为一个线性序列,在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点:除最后一个结点外每一个结点有且仅有一个直接后继结 ...

  3. 栈的理解和代码实现(java)

    从数据结构的角度来看,其实栈也是线性表.特殊性在于栈和队列的基本操作是线性表操作的子集,栈是操作受限制的线性表. 栈的定义 栈是限定仅在表尾进行插入或者删除操作的线性表.对于一个栈来说,表尾端有着特殊 ...

  4. Spring注入方式(2)

    3.引用其他bean Bean经常需要相互协作完成应用程序的功能,bean之间必须能够互相访问,就必须在bean配置之间指定对bean的引用,可以通过节点<ref>或者ref来为bean属 ...

  5. 蓝牙4.0BLE抓包(一) - 搭建EN-Dongle工作环境 使用EN-Dongle抓包 nRF51822

     版权声明:本文为博主原创文章,转载请注明作者和出处.           蓝牙4.0 BLE的开发过程中,使用抓包器进行抓包分析无疑会极大地提高我们的开发效率,同时能帮我们快速的定位问题.对于初学者 ...

  6. Docker for Windows 启动失败,提示Kubernetes证书无效

    起因 部署服务器到一台很久未更新的系统(windows 10),安装docker后,恰好系统自动更新,重启后docker不能启动,提示Kubernetes证书无效(未截到图,抱歉) 排查 因为没有开启 ...

  7. php中各种http报错的状态码分析

    HTTP会经常遇见错误,本文主要和大家分享php中各种http报错的状态码,希望能帮助到大家. HTTP 错误 400 400 请求出错 由于语法格式有误,服务器无法理解此请求.不作修改,客户程序就无 ...

  8. (转)InnoDB存储引擎MVCC实现原理

    InnoDB存储引擎MVCC实现原理 原文:https://liuzhengyang.github.io/2017/04/18/innodb-mvcc/ 简单背景介绍 MySQL MySQL是现在最流 ...

  9. MySQL中show语法

    1. show tables或show tables from database_name; -- 显示当前数据库中所有表的名称. 2. show databases; -- 显示mysql中所有数据 ...

  10. PHPStorm操作小技巧

    1.围绕选中字符输入引号或者括号 2.设置服务器部署 3.隐藏Project快捷键 Shift + Esc 4.IDE内窗口切换 Ctrl + TAB 5.关闭当前项目 File -> Clos ...