luogu题解 P3763 【[TJOI2017]DNA】
题目链接:
思路:
首先我们要用到Rabin-Karp哈希,其实就是这个:
若\(w_{str}\)=(\(a_0\) \(p^{n-1}\)+\(a_1\) \(p^{n-2}\)+...+\(a_{n-1}\) \(p^0\))
所以
\(w_{pre_{i-1}}\) \(=(\) \(a_0\) \(p^{i-1}\)+\(a_1\) \(p^{i-2}\)+...+\(a_{i-1}\) \(p^0\))
\(w_{pre_{j}}\) \(=(\) \(a_0\) \(p^{j}\)+\(a_1\) \(p^{j-1}\)+...+\(a_{j}\) \(p^0\))
所以
\(w_{str_{i,j}}\)
\(=(\) \(a_i\) \(p^{j-i}\)+\(a_{i+1}\) \(p^{j-i-1}\)+...+\(a_{j}\) \(p^0\))
\(=\) \(w_{pre_{j}}\) \(-\) \(w_{pre_{i-1}}\) \(p^{j-i+1}\)
注意了,我这里并没有取模,而是直接直接用unsigned long long 自然溢出,这样更快
然而,一般人都是用二分确定右端点,我自己摸索出了一个骚操作(好像又在哪里听过)----用倍增。
因为在这道题中我觉得二分的上下界可能相差比较大,虽然理论上二分平均情况下更好,但在这道题中实际测出来用倍增更快(如果之后有人用二分跑得还比我快就无视我这句话)。
思路就是这样,其他一些细节就见代码吧.
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#define ri int
const int maxn=100005;
typedef long long ll;
typedef unsigned long long ull;
char a[maxn],b[maxn];
ull q[maxn],aht[maxn],bht[maxn];
int cnt=0,lena,lenb;
inline void Hash(){
ll x=0;
for(ri i=0;a[i];i++){
x=x*131+a[i]-31;
aht[i]=x;
// cout<<x<<i<<endl;
}x=0;
for(ri i=0;b[i];i++){
x=x*131+b[i]-31;
bht[i]=x;
}x=0;
return ;
}
inline int solve(int x,int y){
int k=0,p=1;
x++,y++;
while(p!=0){
if((aht[x+k+p-1]-aht[x-1-1]*q[k+p+1])==(bht[y+k+p-1]-bht[y-1-1]*q[k+p+1]))k+=p,p*=2;
else p=p/2;//cout<<l<<'*'<<r<<'*'<<mid<<endl;
while(x+k+p>lena||y+k+p>lenb)p=p/2;
}
if(a[x-1]==b[y-1])k++;
return k;
}
inline bool ok(int i){
int la=0,k;
for(ri j=1;j<=3;j++){
k=solve(i,la);
i+=k+1,la+=k+1;
if(la>=lenb){return 1;}//cout<<i<<' '<<la<<endl;
}
k=solve(i,la);
i+=k;la+=k;
// cout<<i<<' '<<la<<endl;
if(la>=lenb) return 1;
return 0;
}
int main()
{
int t;
scanf("%d",&t);
q[0]=1;
for(ri i=1;i<=100001;i++)
q[i]=(ull)q[i-1]*131;
//预处理幂,这个技巧来自https://www.cnblogs.com/sineagle/p/8490655.html
while(t--){
int cnt=0;
scanf("%s",a);
scanf("%s",b);
lena=strlen(a),lenb=strlen(b);
if(lena<lenb){printf("0\n");continue;}
Hash();
for(ri i=0;i<lena-lenb+1;i++){
if(ok(i))cnt++;
}
printf("%d\n",cnt);
memset(aht,0,sizeof(aht));
memset(bht,0,sizeof(bht));
}
return 0;
}
后记:
luogu上最快的一次跑了240ms,然而还是比不过BZOJ的dalao
luogu题解 P3763 【[TJOI2017]DNA】的更多相关文章
- [洛谷P3763] [TJOI2017]DNA
洛谷题目链接:[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其 ...
- P3763 [TJOI2017]DNA
链接:https://www.luogu.org/problemnew/show/P3763 题解: 挺水的一题后缀数组 枚举每一个开头用后缀数组判断能否在3次内匹配完
- 洛谷P3763 [Tjoi2017]DNA 【后缀数组】
题目链接 洛谷P3763 题解 后缀数组裸题 在BZOJ被卡常到哭QAQ #include<algorithm> #include<iostream> #include< ...
- 洛谷P3763 [TJOI2017]DNA(后缀数组 RMQ)
题意 题目链接 Sol 这题打死我也不会想到后缀数组的,应该会全程想AC自动机之类的吧 但知道这题能用后缀数组做之后应该就不是那么难了 首先把\(S\)和\(S0\)拼到一起跑,求出Height数组 ...
- 洛谷P3763 [TJOI2017]DNA(后缀自动机)
传送门 好像用SAM写的很少诶…… 其实我一开始也没想到要用SAM的……主要是没有想到找的时候可以dfs…… 首先建一个SAM,然后跑一遍dfs,枚举一下下一位,如果相同直接继续,否则就花费一次次数来 ...
- bzoj4892 [TJOI2017]DNA
bzoj4892 [TJOI2017]DNA 给定一个匹配串和一个模式串,求模式串有多少个连续子串能够修改不超过 \(3\) 个字符变成匹配串 \(len\leq10^5\) hash 枚举子串左端点 ...
- [TJOI2017]DNA --- 后缀数组
[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S, 有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个 ...
- luogu题解P2312解方程--暴力模+秦九韶
题目链接 https://www.luogu.org/problemnew/show/P2312 分析 这道题很毒啊,这么大的数. 但是如果多项式\(\sum_{i=0}^N a[i]*X^i=0\) ...
- [TJOI2017] DNA - 后缀数组,稀疏表
[TJOI2017] DNA Description 求模式串与主串的匹配次数,容错不超过三个字符. Solution 枚举每个开始位置,进行暴力匹配,直到失配次数用光或者匹配成功.考虑到容错量很小, ...
随机推荐
- Restorator软件使exe文件都不能打开,exe不支持此接口
遇到的问题: 下载了一个软件Restorator(资源修改器),填写完注册码之后,所有的exe文件都不能打开了,任务管理器不支持此接口打不开. 问题原因: 软件Restorator关联exe文件,运行 ...
- SQL-W3School-基础:SQL ORDER BY 子句
ylbtech-SQL-W3School-基础:SQL ORDER BY 子句 1.返回顶部 1. ORDER BY 语句用于对结果集进行排序. ORDER BY 语句 ORDER BY 语句用于根据 ...
- ndroid如何监听开机广播和关机广播
需求描述:有些时候,我们需要我们的程序在开机后能自动运行,在系统即将关闭时,能写入一些记录到指定的文件里. 一.开机广播监听: Android系统启动完成后会发出启动完成广播(android.inte ...
- 003-多线程-JUC集合-Set-CopyOnWriteArrayList
一.概述 它是线程安全的无序的集合,可以将它理解成线程安全的HashSet.有意思的是,CopyOnWriteArraySet和HashSet虽然都继承于共同的父类AbstractSet:但是,Has ...
- SQL Server 高级函数汇总【转】
看到一个帖子,博主收集的很全,里面涵盖了一些常用的内置函数,特此收藏下: 原文链接:https://blog.csdn.net/wang1127248268/article/details/53406 ...
- ubuntu kylin 18.04 安装 Qt Creator 5.11
首先,去官网(https://download.qt.io/official_releases/qt/ )下载Qt Creator的安装包. 我下载的是5.11.1版本文件:qt-opensource ...
- Spring Boot连接MySQL报错“Internal Server Error”的解决办法
报错信息如下: {timestamp: "2018-06-14T03:48:23.436+0000", status: 500, error: "Internal Ser ...
- JS创建类和对象,看完了,头就不大了
JavaScript 创建类/对象的几种方式 在JS中,创建对象(Create Object)并不完全是我们时常说的创建类对象,JS中的对象强调的是一种复合类型,JS中创建对象及对对象的访问是极其灵活 ...
- python 操作mysql数据库(mac)包括如何处理安装MySQL-python
一.数据库的安装,https://www.jianshu.com/p/fd3aae701db9 https://jingyan.baidu.com/article/fa4125ac0e3c2 ...
- JavaScript基础------JavaScript语法
js的注释与分号 // 单行注释 /**/多行注释 ctrl +shift +/ 语句结束使用分号,如果省略,则由解析器确定语句的结尾js语法 1.变量.函数名.操作符都区分大小写 2.标识符 (1) ...