题意

题目链接

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. 终于搞定在VS2010中将CString转换为const char*

    最近碰到了CString 转 const char *的问题. 以前只要简单的一个强制转换就OK了,可现在是不行了,搜索了很多资料,终于搞定,主要是Unicode和ANSI的问题,只要做一个转换就可以 ...

  2. mac编辑器vim美化

    mac编辑器vim美化 contents 环境 效果呈现 安装 quick start 环境 mac10.13.6,vim7(该版本mac自带的vim是7),git mac下vim的配置文件有两处 一 ...

  3. C++基础知识-派生类、调用顺序、访问等级、函数遮蔽

    一.派生类的概念 类之间有一种层次关系,有父亲类,有孩子类. 车这个类,当成父类(也叫基类.超类),派生出卡车.轿车,他们属于孩子类(子类.派生类) 继承:有父亲类,有孩子类,构成了层次关系.继承这种 ...

  4. python中TAB补全

    tab补全的代码文件tab.py #!/usr/bin/env python # python startup file import sys import readline import rlcom ...

  5. 威尔逊定理--HDU2973

    参考博客 HDU-2973 题目 Problem Description The math department has been having problems lately. Due to imm ...

  6. DIV盒子介绍

    1.盒子模型=网页布局的基石,由四部分组成: 边框(border).外边距(margin).内边距(padding).盒子中的内容(content) 2.设置顺序是顺时针:上.右.下.左. 三个值(上 ...

  7. 设置npm的镜像源

    将npm的镜像源设置为淘宝镜像源 1.执行命令修改镜像源地址:npm config set registry https://registry.npm.taobao.org 2.重新加载修改后的地址: ...

  8. JAVA list对象排序加去重问题

    对象类实现继承Comparable接口重写compareTo方法实现排序功能,重写equals方法实现去重功能(根据ID去重)public class TestAbilityAnalyze imple ...

  9. sessionKey/tokenKey

    移动端维持登录状态的机制 1. sessionKey/tokenKey哪里来? 1. 登录成功之后,后台返回. 2. sessionKey/tokenKey生成有什么规则? 1. 后台返回的,按照一定 ...

  10. django notes 七:Using Forms

    form 也没什么可说的,我只给一个例子大家就懂了 form model from django import forms class UserForm(forms.Form): username = ...