bzoj4892
后缀数组
先开始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的更多相关文章
- bzoj4892 [TJOI2017]DNA
		
bzoj4892 [TJOI2017]DNA 给定一个匹配串和一个模式串,求模式串有多少个连续子串能够修改不超过 \(3\) 个字符变成匹配串 \(len\leq10^5\) hash 枚举子串左端点 ...
 - BZOJ4892 Tjoi2017dna(后缀数组)
		
对每个子串暴力匹配至失配三次即可.可以用SA查lcp.然而在bzoj上被卡常了.当然也可以二分+哈希或者SAM甚至FFT. #include<iostream> #include<c ...
 - 【BZOJ4892】DNA(后缀数组)
		
[BZOJ4892]DNA(后缀数组) 题面 BZOJ 洛谷 题解 看到这道题目,我第一反应是\(FFT\)??? 然后大力码出了一个\(FFT\) 就像这样 #include<iostream ...
 - BZOJ4892:[TJOI2017]dna(hash)
		
Description 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表 ...
 - [BZOJ4892][TJOI2017]DNA(后缀数组)
		
题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状 ...
 - 字符串Hash/树Hash学习笔记
		
哈希 Tags:字符串 作业部落 评论地址 一.概述 百度百科: 散列表(Hash table/哈希表),是根据关键码值(Key value)而直接进行访问的数据结构. 哈希表常用于比较两个字符串是否 ...
 - FFT_应用和例题
		
卷积 现有两个定义在 N 上的函数 \(f(n),g(n)\),定义 \(f\) 和 \(g\) 的卷积(convolution)为 \(f \otimes g\) \[ (f \otimes g)( ...
 
随机推荐
- 百度地图SDK调试SDKInitializer.initialize(getApplicationContext())错误
			
首先描写叙述下问题出现的原因.開始的时候写了一个百度地图SDK的demo来试功能,由于最開始用的是Eclipse自带的AVD来调试,一切正常. 都能够正常验证,可是由于受不了重复的重新启动AVD设备, ...
 - php.ini的载入位置
			
php.ini文件找不到,载入WINDOS下的,但找不到,后来强制-c查找是OK的.思考,为什么载入window下的ini文件.1.可能是有一个默认路径.2.可能没有路径.默认载入. 问题解决:htt ...
 - css3 position fixed居中的问题
			
通常,我们要让某元素居中,会这样做: #element{ margin:0 auto; } 假设还想让此元素位置固定呢?一般我们会加入position:fixed,例如以下: #element{ po ...
 - SqlServer查询语句中用到的锁
			
前段时间**公司DBA来我们这培训.讲了一大堆MYSQL的优化. QA环节一程序员问“SQL语句中的 with nolock 除了不锁表外,是否能读其他锁住的数据". 讲课的人嘟嘟了半天没解 ...
 - idea2018注册方法
			
下面是具体的破解激活步骤: 1. 下载破解补丁文件,路径为:http://idea.lanyus.com/jar/JetbrainsCrack-2.7-release-str.jar 2.将补丁放在安 ...
 - 数据迁移实战:基于Kettle的Mysql到DB2的数据迁移
			
From:https://my.oschina.net/simpleton/blog/525675 一.什么是ETL ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数 ...
 - Java依照List内存储的对象的某个字段进行排序
			
关键点:将List内存储的对象实现Comparable类.重写它的compareTo()方法就可以 Bean: package chc; public class StuVo implements C ...
 - POJ 3335 Rotating Scoreboard(半平面交 多边形是否有核 模板)
			
题目链接:http://poj.org/problem? id=3335 Description This year, ACM/ICPC World finals will be held in a ...
 - 如何清除本地DNS缓存 windows
			
在您的网站迁移服务器时需要对域名所指向的IP进行更改,这时候在本机访问网站时就需要清除本地的DNS缓存信息,那么怎样清除呢? 首先我们应该明白清除DNS缓存信息的原理:当计算机对域名访问时并不是每次访 ...
 - ORACLE时间函数(SYSDATE)简析
			
ORACLE时间函数(SYSDATE)简析 分类: 原文地址:ORACLE时间函数(SYSDATE)简析 作者:skylway 加法 select sysdate,add_months(sysdate ...