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. std::shared_ptr<void>的工作原理

    前戏 先抛出两个问题 如果delete一个指针,但是它真实的类型和指针类型不一样会发生什么? 是谁调用了析构函数? 下面这段代码会发生什么有趣的事情? // delete_diff_type.cpp ...

  2. SpringMVC 返回json的两种方式

    前后台数据交互使用json是一种很重要的方式.本文主要探讨SpringMVC框架使用json传输的技术. 请注意,本文所提到的项目使用Spring 版本是4.1.7,其他版本在具体使用上可能有不一样的 ...

  3. Java中的UDP应用

    我在<JavaSE项目之聊天室>中通过遵守TCP协议的ServerSocket与Socket实现了聊天室的群聊窗口.同时,在介绍OSI与TCP/IP参考模型时,也曾提及TCP与UDP(全称 ...

  4. 日志框架之Logback

    1 日志框架选择 日志门面:SLF4J 日志实现:Logback 2 实现控制台的日志打印输出01 2.1 在需要实现日志信息打印的类中实例化Logger对象 private final Logger ...

  5. bzoj 4199 [NOI2015]寿司晚宴

    Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同 ...

  6. [C#]使用Redis来存储键值对(Key-Value Pair)

    本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.5及以 ...

  7. form表单与后台请求的关系

    开发中遇到一个问题,说这个问题前先看一下代码 后台方面, get请求: post请求: 前端方面: 问题是:当我点击提交表单后,页面会跳转成这样: 经过多番测试,原因竟是form表单的提交问题,如果用 ...

  8. BLE抓包是怎么回事儿?

    BLE抓包 在进行网络开发的时候,抓包是一个很重要的调试过程,通过抓包可以分析网络传输的数据是否正确,可以深入理解网络传输过程.在物联网开发中,BLE低功耗蓝牙技术是一种非常通用的网络传输方式.在学习 ...

  9. C# 防止同时调用=========使用读写锁三行代码简单解决多线程并发的问题

    http://www.jb51.net/article/99718.htm     本文主要介绍了C#使用读写锁三行代码简单解决多线程并发写入文件时提示"文件正在由另一进程使用,因此该进程无 ...

  10. 每天学一点Docker(2)

    容器runtime 容器runtime是容器真正运行的地方,runtime需要和操作系统kernel紧密结合,为容器提供运行环境. 比如说,java程序比作一个容器,JVM就是runtime.JVM为 ...