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. 36、IO模型与socketserver实现并发

    特别声明本随笔copy于egon(林海峰). 一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronou ...

  2. python爬虫小结1

    先看正则化,正则化就是描述命令和字符切分.查找.筛选等功能的方便方式. http://www.cnblogs.com/fnng/archive/2013/05/20/3089816.html 一个游戏 ...

  3. 33 款主宰 2017 iOS 开发的开源库

    推荐一篇文章 改文章汇聚了现在主流的一些三方框架,很值得一看 https://mp.weixin.qq.com/s/ICodliohtzbmA-eLKRFT-Q

  4. 使用node的fs读取文件

    啊啊啊啊啊啊啊啊啊啊啊啊啊啊,被node的fs坑了一下午,我又爬上来了,要坚强的笑着活下去,嗯,没毛病老铁. let http = require('http'); let fs = require( ...

  5. iOS ShareSDK 三方分享/登录使用

    原文 http://www.cnblogs.com/CoderAlex/p/4860352.html 一: 快速集成 1.前言 作为现在App里必不可少的用户分享需要,社交化分享显然是我们开发app里 ...

  6. SP的封装(数据持久化方式一)

    1.先看一段描述: Interface for accessing and modifying preference data returned by Context.getSharedPrefere ...

  7. locate 命令详解

    locate :http://www.cnblogs.com/peida/archive/2012/11/12/2765750.html 作用:locate命令可以在搜寻数据库时快速找到档案,数据库由 ...

  8. Delete 命令详解

    cp:复制文件 /cp -r:复制目录  /bin/cp -f: 复制文件并覆盖已有文件(写命令的绝对路径/bin/)  /cp /ect/passwd .:将其他文件复制到当前目录  /-n :不要 ...

  9. Java 向下转型

    1.Java 中父类直接向子类转型的不合法的,可以编译但运行时报错. Java中子类直接向父类转型 是合法的,但转型后,可以执行的方法仅限存在于父类中的,在执行时,先看子类的是否有定义,有就执行,没有 ...

  10. 正确使用volatile场景--状态标志

    同步机制:volatile 特点:可见性:不具备原子性 每个线程有自己单独的内存:如果线程1和线程2公用一个变量name:如果两个线程并发进行,并且需要访问变量name:如果这个变量具有了可见性,线程 ...