Description

 

为了给Wind买生日礼物,Jiajia不得不找了一份检查文本的工作。这份工作很无聊:给你一段文本 
要求比对从文本中某两个位置开始能匹配的最大长度是多少。但比无聊更糟糕的是,Jiajia的经理 
还可能往文本里面插入一些字符。 
Jiajia想用一个程序来解决这些繁琐的工作。这个程序的速度要足够快,因为Wind的生日就快要到了 
Jiajia必须赚到足够多的钱,也就是处理足够多的文本。

Input

输入文件第一行是原始文本。 
输入文件第二行是操作数n。此后n行,每行描述一条命令,命令有两种形式: 
I ch p:表示将一个字符ch插入到当前文本的第p个字符之前,如果p大于当前文本长度则表示插入到当前文本末尾; 
Q i j:表示询问当前文本从原始文本的第i个和第j个字符现在所在的位置开始能匹配的字符是多少。 
你可以认为文本初始长度不超过50000,I命令最多200条,Q命令最多20000条。

Output

对于每条Q命令输出一行,为最长匹配长度。

Sample Input

abaab
5
Q 1 2
Q 1 3
I a 2
Q 1 2
Q 1 3

Sample Output

0
1
0
3
 
直接hash暴力重构==1196 ms(bzoj)
treap维护hash==5512 ms(bzoj)
spaly维护hash==TLE
gg……
感谢居神贡献权限号
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MN 100001
using namespace std;
int read_p,read_ca;
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
unsigned long long hash[MN],mi[MN];
char c[MN],p[];
int n,m,ne[MN],pos,len,x,y;
inline void build(int x){
for (int i=x;i<=len;i++) hash[i]=hash[i-]*+c[i];
}
inline int query(int x,int y){
if (x>y) swap(x,y);
int l=,r=len-y+,mid;
while (l<r){mid=(l+r+)>>;if (hash[x+mid-]-hash[x-]*mi[mid]==hash[y+mid-]-hash[y-]*mi[mid]) l=mid;else r=mid-;}
return l;
}
int main(){
scanf("%s",c+);
n=read();
m=len=strlen(c+);
mi[]=;
for (int i=;i<=m+;i++) mi[i]=mi[i-]*;
for (int i=;i<=len;i++) ne[i]=i;
build();
for (int i=;i<=n;i++){
scanf("%s",p);
if (p[]=='I'){
scanf("%s",p);pos=read();
if (pos>len) pos=len+;
for (int i=len;i>=pos;i--) c[i+]=c[i];
c[pos]=p[];len++;
build(pos);
for (int i=m;i;i--) if (ne[i]>=pos) ne[i]++;else break;
}else{
x=read();y=read();
printf("%d\n",query(ne[x],ne[y]));
}
}
}

大暴力 2856 kb 1196 ms 1350 B

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define MN 100001
using namespace std;
int read_p,read_ca;
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
unsigned long long mi[MN];
char c[MN],p[];
int n,m,ne[MN],pos,len,x,y;
struct tree{
int l,r,s,f,fa;
unsigned long long h,c;
tree(){
l=r=s=h=c=;
}
};
struct s_tree{
int root,size;
tree t[];
s_tree(){
root=size=;
}
inline void up(int x){
t[x].h=(t[t[x].l].h*+t[x].c)*mi[t[t[x].r].s]+t[t[x].r].h;
}
inline void rir(int &x){
int k=t[x].r;
t[x].r=t[k].l;
t[k].l=x;
t[t[x].r].fa=x;
t[k].fa=t[x].fa;
t[x].fa=k;
t[k].s=t[x].s;
t[x].s=+t[t[x].l].s+t[t[x].r].s;
t[k].h=t[x].h;up(x);
x=k;
}
inline void lir(int &x){
int k=t[x].l;
t[x].l=t[k].r;
t[k].r=x;
t[t[x].l].fa=x;
t[k].fa=t[x].fa;
t[x].fa=k;
t[k].s=t[x].s;
t[x].s=+t[t[x].l].s+t[t[x].r].s;
t[k].h=t[x].h;up(x);
x=k;
}
inline void insert(int &p,int x,int c,int f){
if (!p){
p=++size;
t[p].c=c;
t[p].h=c;
t[p].s=;
t[p].f=rand();
t[p].fa=f;
}else{
t[p].s++;
if (t[t[p].l].s+>=x){
insert(t[p].l,x,c,p);
if (t[t[p].l].f<t[p].f) lir(p);
}else{
insert(t[p].r,x--t[t[p].l].s,c,p);
if (t[t[p].r].f<t[p].f) rir(p);
}
}
up(p);
}
inline int ne(int x){
int mmh=;
while (x){
mmh+=t[t[x].l].s+;
while (t[x].fa&&t[t[x].fa].l==x) x=t[x].fa;
x=t[x].fa;
}
return mmh;
}
inline unsigned long long hash(int p,int x){
if ((!x)||(!p)) return ;
if (t[t[p].l].s==x-) return t[t[p].l].h*+t[p].c;else
if (t[t[p].l].s>=x) return hash(t[p].l,x);else return (t[t[p].l].h*+t[p].c)*mi[x-t[t[p].l].s-]+hash(t[p].r,x--t[t[p].l].s);
}
}t;
inline int query(int x,int y){
x=t.ne(x);y=t.ne(y);
if (x>y) swap(x,y);
int l=,r=len-y+,mid;
while (l<r){mid=(l+r+)>>;if (t.hash(t.root,x+mid-)-t.hash(t.root,x-)*mi[mid]==t.hash(t.root,y+mid-)-t.hash(t.root,y-)*mi[mid]) l=mid;else r=mid-;}
return l;
}
int main(){
scanf("%s",c+);
n=read();
m=len=strlen(c+);
mi[]=;
for (int i=;i<=1e5;i++) mi[i]=mi[i-]*;
for (int i=;i<=len;i++) ne[i]=i;
for (int i=;i<=len;i++) t.insert(t.root,i,c[i],);
for (int i=;i<=n;i++){
scanf("%s",p);
if (p[]=='I'){
scanf("%s",p);pos=read();
if (pos>len) pos=len+;t.insert(t.root,pos,p[],);
len++;
}else{
x=read();y=read();
printf("%d\n",query(x,y));
}
}
}

treap 5604 kb 5512 ms 2929 B

暴力又短又快……有毒……

poj 2758 && BZOJ 2258 Checking the Text 文本校对的更多相关文章

  1. POJ 2758 Checking the Text(Hash+二分答案)

    [题目链接] http://poj.org/problem?id=2758 [题目大意] 给出一个字符串,支持两个操作,在任意位置插入一个字符串,或者查询两个位置往后的最长公共前缀,注意查询的时候是原 ...

  2. HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT

    一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...

  3. POJ 1061 BZOJ 1477 Luogu P1516 青蛙的约会 (扩展欧几里得算法)

    手动博客搬家: 本文发表于20180226 23:35:26, 原地址https://blog.csdn.net/suncongbo/article/details/79382991 题目链接: (p ...

  4. bzoj 2258 splay

    类似于1014,用splay维护这个序列,维护每个节点为根的子树的hash值,对于一个询问二分答案判断就行了. 反思:询问的时候因为是原序列的x,y,所以开始的时候直接splay(x-1)了,后来发现 ...

  5. [POJ 2373][BZOJ 1986] Dividing the Path

    Link: POJ 2373 传送门 Solution: 一开始想错方向的一道简单$dp$,不应该啊…… 我一开始的想法是以$cows' ranges$的节点为状态来$dp$ 但明显一个灌溉的区间的两 ...

  6. POJ 1987 BZOJ 3365 Distance Statistics 树的分治(点分治)

    题目大意:(同poj1741,刷一赠一系列) CODE: #include <cstdio> #include <cstring> #include <iostream& ...

  7. poj 2434;bzoj 1686 [Usaco2005 Open]Waves 波纹

    Description Input     第1行:四个用空格隔开的整数Pj Bi,B2,R. P(1≤P≤5)表示石子的个数,Bi(-5×100000≤Bi≤5×100000)和B2(-5×1000 ...

  8. POJ2758 Checking the Text 哈希

    注意到插入次数挺少的,于是每次暴力重构,然后哈希+二分 #include<cstdio> #include<iostream> #include<algorithm> ...

  9. poj-2758 Checking the Text

    题意: 给定一个字符串,要求维护两种操作: I:在字符串中插入一个字符: Q:询问某两个位置開始的LCP. 插入操作<=200,字符串长度<=5w,查询操作<=2w: 题解: 第一道 ...

随机推荐

  1. 【java设计模式】【创建模式Creational Pattern】抽象工厂模式Abstract Factory Pattern

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW0AAABvCAIAAACo3AbKAAALvUlEQVR4nO1dUa7cOA7U/c+zwJxkf4

  2. JS判断终端

    //判断手机终端 if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) { window.location.href = 'mobil ...

  3. Function:html结构转字符串形式显示

    //Html结构转字符串形式显示 支持<br>换行 function ToHtmlString(htmlStr) { return toTXT(htmlStr).replace(/\&am ...

  4. Java I/O---概述

    对于程序设计者来说,创建一个好的输入/输出系统(I/O)系统是一项艰难的任务. 现在大量不同方案已经说明了这一点.挑战似乎来自于要涵盖所有的可能性.不仅存在各种I/O源端和想要与之通信的接收端(文件. ...

  5. cd 命令详解

    cd 命令 作用:  cd 用来切换目录,目录表示法可为绝对路径或相对路径, 若目录名称省略,则变换至使用者的登陆目录. ~ 可表示为家目录,.为当前目录,..为上级目录 语法: cd (选项)(参数 ...

  6. Jmeter+Ant+Jenkins接口自动化测试(二)_测试方案设计及jmeter脚本开发

    前言 根据之前部署好的测试环境,进行接口自动化测试的方案设计及Jmeter脚本开发.测试方案设计过程中采用了数据分离和对象分离等思路,因此直接通过特定的测试用例文档来驱动整个自动化接口测试的执行,相关 ...

  7. 发布 Google Chrome插件教程

    换个视角,世界不一样.嘘~~~ 如果你会使用js的话,那么你就可以自己动手写一个chrome插件,而且非常容易.google是一个全球化的平台,想想自己的程序被世界人民所使用,是不是很激动? 注册开发 ...

  8. 遍历文件 创建XML对象 方法 python解析XML文件 提取坐标计存入文件

    XML文件??? xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. 里面的标签都是可以随心所欲的按照他的命名规则来定义的,文件名为roi.xm ...

  9. 第四章初始CSS3预习笔记

    第四章 初始CSS3预习笔记 一: 1: 什么是CSS? 全称是层叠样式表;/通常又称为风格样式表,.他是用来进行网页风格设计的; 2:CSS的优势: 1>内容以表现分离,即使用u前面学习的HT ...

  10. 数据库和 MySQL 简介(真的只是简介)

    数据库 si 什么? google.com baidu.com 数据库服务器,数据管理系统,数据库,表与记录的关系