后缀数组

先开始nc了,觉得自动机做法是指数级的,就写了个后缀数组

具体方法是暴力,枚举起点,然后用lcp向后暴力匹配,如果失配就减少一次,我们一共有3次机会,这样每次匹配复杂度是O(1)的,所以总复杂度是O(nlogn+n),然后t掉了,交了发别人代码,bzoj怎么那么慢,洛谷跑的飞快。调了很长时间发现sa板子写错了,明明是粘过来的。。。

后缀自动机就是在自动机上匹配,如果不匹配可以随便走,每次匹配完统计就行了

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + ;
int n, m, k, len, pos, ans;
char s[N], t[N];
int p[N], a[N], b[N], rank[N], lcp[N], sa[N], mn[N][], mp[], Log[N], tmp[N];
void radix(int *s, int *a, int *b, int n, int m)
{
int count[N]; memset(count, , sizeof(count));
for(int i = ; i <= n; ++i) ++count[s[a[i]]];
for(int i = ; i <= m; ++i) count[i] += count[i - ];
for(int i = n; i; --i) b[count[s[a[i]]]--] = a[i];
}
void Sa(int *s, int n)
{
for(int i = ; i <= n; ++i) rank[i] = i;
radix(s, rank, sa, n, );
rank[sa[]] = ;
for(int i = ; i <= n; ++i) rank[sa[i]] = rank[sa[i - ]] + (s[sa[i]] != s[sa[i - ]]);
for(int k = ; k <= n; k <<= )
{
for(int i = ; i <= n; ++i)
{
a[i] = rank[i];
b[i] = i + k <= n ? rank[i + k] : ;
sa[i] = i;
}
radix(b, sa, rank, n, n);
radix(a, rank, sa, n, n);
rank[sa[]] = ;
for(int i = ; i <= n; ++i) rank[sa[i]] = rank[sa[i - ]] + (a[sa[i]] != a[sa[i - ]] || b[sa[i]] != b[sa[i - ]]);
}
}
void Lcp(int *s, int n)
{
int h = ;
for(int i = ; i <= n; ++i) rank[sa[i]] = i;
for(int i = ; i <= n; ++i)
{
int j = sa[rank[i] - ];
if(rank[i] <= ) continue;
if(h > ) --h;
for(; i + h <= n && j + h <= n; ++h) if(s[i + h] != s[j + h]) break;
mn[rank[i] - ][] = h;
}
for(int j = ; j <= ; ++j)
for(int i = ; i + ( << j) - <= n; ++i)
mn[i][j] = min(mn[i][j - ], mn[i + ( << (j - ))][j - ]);
}
int query(int l, int r)
{
l = rank[l];
r = rank[r];
if(l > r) swap(l, r);
--r;
int x = Log[r - l + ];
return min(mn[l][x], mn[r - ( << x) + ][x]);
}
int main()
{
int T;
scanf("%d", &T);
mp['A'] = ;
mp['G'] = ;
mp['C'] = ;
mp['T'] = ;
for(int i = ; i < N; ++i) Log[i] = Log[i >> ] + ;
while(T--)
{
ans = ;
scanf("%s%s", s + , t + );
len = ;
n = strlen(s + );
m = strlen(t + );
for(int i = ; i <= n; ++i) p[++len] = mp[s[i]];
p[++len] = ;
pos = len + ;
for(int i = ; i <= m; ++i) p[++len] = mp[t[i]];
Sa(p, len);
Lcp(p, len);
for(int i = ; i <= n - m + ; ++i)
{
int tmp = m, cnt = , p1 = i, p2 = pos;
while(tmp > )
{
int x = query(p1, p2);
tmp -= x;
p1 += x;
p2 += x;
if(tmp <= ) break;
while(cnt >= && p[p1] != p[p2] && p1 <= n && p2 <= len)
{
++p1;
++p2;
--tmp;
--cnt;
}
if(cnt < || p2 > len || p1 > n) break;
}
if(cnt >= && tmp <= ) ++ans;
}
printf("%d\n", ans);
}
return ;
}

bzoj4892的更多相关文章

  1. bzoj4892 [TJOI2017]DNA

    bzoj4892 [TJOI2017]DNA 给定一个匹配串和一个模式串,求模式串有多少个连续子串能够修改不超过 \(3\) 个字符变成匹配串 \(len\leq10^5\) hash 枚举子串左端点 ...

  2. BZOJ4892 Tjoi2017dna(后缀数组)

    对每个子串暴力匹配至失配三次即可.可以用SA查lcp.然而在bzoj上被卡常了.当然也可以二分+哈希或者SAM甚至FFT. #include<iostream> #include<c ...

  3. 【BZOJ4892】DNA(后缀数组)

    [BZOJ4892]DNA(后缀数组) 题面 BZOJ 洛谷 题解 看到这道题目,我第一反应是\(FFT\)??? 然后大力码出了一个\(FFT\) 就像这样 #include<iostream ...

  4. BZOJ4892:[TJOI2017]dna(hash)

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

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

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

  6. 字符串Hash/树Hash学习笔记

    哈希 Tags:字符串 作业部落 评论地址 一.概述 百度百科: 散列表(Hash table/哈希表),是根据关键码值(Key value)而直接进行访问的数据结构. 哈希表常用于比较两个字符串是否 ...

  7. FFT_应用和例题

    卷积 现有两个定义在 N 上的函数 \(f(n),g(n)\),定义 \(f\) 和 \(g\) 的卷积(convolution)为 \(f \otimes g\) \[ (f \otimes g)( ...

随机推荐

  1. 更改已经签名的app中的内容

    转载请说明出处http://blog.csdn.net/andywuchuanlong 记得上次在南昌中兴的一个项目中遇到过一个这种需求:一个app能够给多个渠道商去运营,渠道商推广出去能够获得对应的 ...

  2. Mina、Netty、Twisted一起学(七):公布/订阅(Publish/Subscribe)

    消息传递有非常多种方式.请求/响应(Request/Reply)是最经常使用的.在前面的博文的样例中.非常多都是採用请求/响应的方式.当server接收到消息后,会马上write回写一条消息到clie ...

  3. 如何去掉Google搜索的跳转 让你的Google搜索不被reset掉

    http://www.nowamagic.net/librarys/veda/detail/389 在点击google搜索结果时,google会在结果的URL前做个跳转,且有时这个跳转地址会被墙,这样 ...

  4. FTPClient listFiles 阻塞问题

    Android端使用 FTPClient 实现上传文件到到filezilla server(filezilla server部署在阿里云服务器)出现 listFiles阻塞.具体的现象是 Ftp Cl ...

  5. 超越MySQL:三个流行MySQL分支的对比(转)

    导读:尽管MySQL是最受欢迎的程序之一,但是许多开发人员认为有必要将其拆分成其他项目,并且每个分支项目都有自己的专长.该 需求以及Oracle对核心产品增长缓慢的担忧,导致出现了许多开发人员感兴趣的 ...

  6. mysql字符太长警告

    用navicateclient,打开相应的数据库. 打开函数.找相应的val()函数,进行编辑,就能够!编辑范围为4000

  7. 后台运行命令:&amp;和nohup command &amp; 以及关闭、查看后台任务

    当我们在终端或控制台工作时.可能不希望由于执行一个作业而占住了屏幕,由于可能还有更重要的事情要做,比方阅读电子邮件. 对于密集訪问磁盘的进程,我们更希望它可以在每天的非负荷高峰时间段执行(比如凌晨). ...

  8. Android性能优化之中的一个 布局优化

    本文为Android性能优化--布局优化,主要介绍使用抽象布局标签(include, viewstub, merge).去除不必要的嵌套和View节点.降低不必要的infalte及其它Layout方面 ...

  9. Linux高端内存

    Linux高端内存是针对物理内存来说的,虚拟内存没有高端这个概念.Linux系统将虚拟内存分为两个部分,即用户地 址空间和内核地址空间,对于32位系统来说,虚拟地址空间为4GB,其中用户空间范围为0- ...

  10. 在jquery的ajax方法中的success中使用return要注意的问题

    jquery的ajax方法:在success中使用return:来结束程序的时候,结束的只是success这个方法,也就是说success中的return的作用范围只是success: 如果要想在su ...