题意

题目链接

Sol

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

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

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

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

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

rmq维护一下区间lcp最小值

BZOJ上被完美卡常

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
const int INF = 2333;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M, L, rak[MAXN], tax[MAXN], tp[MAXN], sa[MAXN], H[MAXN], f[MAXN][20], lg2[MAXN];
char s[MAXN], s0[MAXN];
void Qsort() {
for(int i = 0; i <= M; i++) tax[i] = 0;
for(int i = 1; i <= N; i++) tax[rak[i]]++;
for(int i = 1; i <= M; i++) tax[i] += tax[i - 1];
for(int i = N; i >= 1; i--) sa[tax[rak[tp[i]]]--] = tp[i];
}
void SuffixSort() {
for(int i = 1; i <= N; i++) rak[i] = s[i], tp[i] = i; M = 233; Qsort();
for(int w = 1, p = 0; p < N; w <<= 1, M = p) { p = 0;
for(int i = 1; i <= w; i++) tp[++p] = N - i + 1;
for(int i = 1; i <= N; i++) if(sa[i] > w) tp[++p] = sa[i] - w;
Qsort(); swap(tp, rak); rak[sa[1]] = p = 1;
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;
}
for(int i = 1, k = 0; i <= N; i++) {
if(k) k--; int j = sa[rak[i] - 1];
while(s[i + k] == s[j + k]) k++;
H[rak[i]] = k;
}
}
void Pre() {
for(int i = 1; i <= N; i++) f[i][0] = H[i];
for(int j = 1; j <= 17; j++)
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]);
}
int Query(int x, int y) {
if(x > y) swap(x, y); x++;
int k = lg2[y - x + 1];
return min(f[x][k], f[y - (1 << k) + 1][k]);
}
int check(int x, int y, int dep) {
if(dep == 3) return Query(rak[x], rak[y]);
int num = Query(rak[x], rak[y]);
num += check(x + num + 1, y + num + 1, dep + 1) + 1;
return num;
}
void solve() {
scanf("%s%s", s + 1, s0 + 1);
L = strlen(s0 + 1); N = strlen(s + 1);
for(int i = 1; i <= L; i++) s[N + i] = s0[i];
N += L;
SuffixSort(); Pre(); N -= L; int ans = 0;
for(int i = 1; i <= N - L + 1; i++) if(check(i, N + 1, 0) >= L) ans++;
printf("%d\n", ans);
}
int main() {
//freopen("a.in", "r", stdin);
lg2[1] = 0; for(int i = 2; i <= MAXN - 1; i++) lg2[i] = lg2[i >> 1] + 1;
for(int T = read(); T; solve(), T--);
return 0;
}
/*
2
ATCGCCCTA
CTTCA
ATCGCCCTA
CTTCA
*/

洛谷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. 前端IDE:VSCode + WebStorm

    VSCode 插件安装 官网:Extensions for the Visual Studio family of products: (1)拼接下载链接: https://${publisher}. ...

  2. JavaScript的几种(原型)继承

    定义Foo,Bar 其中,Bar继承Foo a是Bar的实例,包含有Foo和Bar的函数和属性: function Foo(name) { this.name = name; } Foo.protot ...

  3. c++之选择排序和冒泡排序实现

     1.冒泡排序 冒泡排序就是通过对比前一个和后一个数的大小,按照规则进行顺序的调换.每一轮对比之后最大或者最小值都会浮到最上面或者沉到最低下. 如:对这一数组进行冒泡排序:int a[5]{34,12 ...

  4. 浅谈postMessage跨域通信与localStorage实现跨域共享

    https://www.cnblogs.com/tyrion1990/p/8134384.html

  5. 二分难题 && deque

    141. Sqrt(x) https://www.lintcode.com/problem/sqrtx/description?_from=ladder&&fromId=4 publi ...

  6. centos 7 上安装 testlink 1.9.15/1.9.16/1.9.17/1.9.18 (mysql/php/httpd)

    1.9.18 的System Requirements - server.注意,适用于 1.9.15 及以后. Server environment should consist of: web-se ...

  7. (转)分布式中使用Redis实现Session共享(一)

    上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...

  8. (转载)IDEA新建项目时,没有Spring Initializr选项

    最近开始使用IDEA作为开发工具,然后也是打算开始学习使用spring boot. 看着博客来进行操作上手spring boot,很多都是说 创建一个新项目(Create New Project) 选 ...

  9. smarty 教程 及 常用点

    1. 简单例子 有助回忆基本知识点 define("DIR",dirname(__FILE__)); require_once(DIR."/libs/Smarty.cla ...

  10. html/css元素

    块级元素 会独占一行,多个block元素会各自新起一行.默认情况下,block元素宽度自动填满其父元素宽度. 可以设置width,height属性.块级元素即使设置了宽度,仍然是独占一行. 可以设置m ...