2105: 增强型LCP

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 366  Solved: 86
[Submit][Status]

Description

Input

Output

对于每个Lcp(a,b)操作输出最长公共前缀

Sample Input

47
abab
L 13
A 1 ab
L 1 3
C 56 cb
L 1 3
D 1 2
L 1 3

Sample Output

2
4
2
0

HINT

Source

题解:
这题。。。
原来一直以为是个splay练手题,于是昨天来写。。。
2h没调出来,今天来了发现pushup写错了。。。T_T
然后就是狂T了。。。
看题解发现我们暴力重构写hash就行了,因为修改少,我也是醉了。。。
然后终于会了字符串的hash算法
我们另b[i]=si-sn的hash值,递推式b[i]=b[i+1]*base+s[i]
然后我们要得到从i开始的len长度的hash就是 b[i]-b[i+len]*a[len]  a[len]表示base^len
还有c++的字符串问题
s,insert(pos,st) 表示在pos前插入st
s.erase(pos,len)表示从pos开始删除len的字符,包括pos
代码:

 #include<cstdio>

 #include<cstdlib>

 #include<cmath>

 #include<cstring>

 #include<algorithm>

 #include<iostream>

 #include<vector>

 #include<map>

 #include<set>

 #include<queue>

 #include<string>

 #define inf 1000000000

 #define maxn 1000000+5

 #define maxm 500+100

 #define eps 1e-10

 #define ull unsigned long long

 #define pa pair<int,int>

 #define for0(i,n) for(int i=0;i<=(n);i++)

 #define for1(i,n) for(int i=1;i<=(n);i++)

 #define for2(i,x,y) for(int i=(x);i<=(y);i++)

 #define for3(i,x,y) for(int i=(x);i>=(y);i--)

 #define mod 1000000007
#define base 13131 using namespace std; inline int read() { int x=,f=;char ch=getchar(); while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();} while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();} return x*f; }
int n,m,q;
ull a[maxn],b[maxn];
char ch[maxn];
string s;
inline void rebuild()
{
n=s.length();
b[n-]=s[n-];
for3(i,n-,)b[i]=b[i+]*base+(ull)s[i];
}
inline ull get(int x,int l){return b[x]-b[x+l]*a[l];} int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); n=read();q=read();
scanf("%s",ch);s=ch;
a[]=;
for1(i,maxn-)a[i]=a[i-]*(ull)base;
rebuild();
while(q--)
{
scanf("%s",ch);
if(ch[]=='L')
{
int x=read()-,y=read()-,l=,r=n-y;
while(l<=r)
{
int mid=(l+r)>>;
if(get(x,mid)==get(y,mid))l=mid+;else r=mid-;
}
printf("%d\n",r);
}
else if(ch[]=='A')
{
int x=read()-;
scanf("%s",ch);
s.insert(x,ch);
rebuild();
}
else if(ch[]=='C')
{
int x=read()-,y=read()-;
scanf("%s",ch);
for2(i,x,y)s[i]=ch[i-x];
rebuild();
}
else
{
int x=read()-,y=read()-;
s.erase(x,y-x+);
rebuild();
}
} return ; }

再贴一下splay的代码,sad story。。。

代码:

 #include<cstdio>

 #include<cstdlib>

 #include<cmath>

 #include<cstring>

 #include<algorithm>

 #include<iostream>

 #include<vector>

 #include<map>

 #include<set>

 #include<queue>

 #include<string>

 #define inf 1000000000

 #define maxn 1000000+5

 #define maxm 500+100

 #define eps 1e-10

 #define ull unsigned long long

 #define pa pair<int,int>

 #define for0(i,n) for(int i=0;i<=(n);i++)

 #define for1(i,n) for(int i=1;i<=(n);i++)

 #define for2(i,x,y) for(int i=(x);i<=(y);i++)

 #define for3(i,x,y) for(int i=(x);i>=(y);i--)

 #define mod 1000000007

 using namespace std;

 inline int read()

 {

     int x=,f=;char ch=getchar();

     while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}

     while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}

     return x*f;

 }
int n,m,q,xx,yy,rt,tot,id[maxn],s[maxn],c[maxn][],fa[maxn];
ull v[maxn],sum[maxn],hash[maxn];
char st[maxn];
inline void pushup(int x)
{
if(!x)return;
int l=c[x][],r=c[x][];
s[x]=s[l]+s[r]+;
sum[x]=sum[r]+v[x]*hash[s[r]]+sum[l]*hash[s[r]+];
//if(x==7)cout<<x<<' '<<l<<' '<<r<<' '<<sum[x]<<' '<<sum[r]<<' '<<s[r]<<' '<<v[x]<<endl;
}
inline void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l=c[y][]==x,r=l^;
if(y!=k)c[z][c[z][]==y]=x;else k=x;
//cout<<x<<' '<<y<<' '<<z<<endl;
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
inline void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k)
{
if((c[z][]==y)^(c[y][]==x))rotate(x,k);else rotate(y,k);
}
rotate(x,k);
}
}
void build(int l,int r,int f)
{
if(l>r)return;
int mid=(l+r)>>,x=id[mid]=++tot,y=fa[x]=id[f];
v[x]=st[mid];c[y][mid>f]=x;
if(l==r)
{
sum[x]=v[x];s[x]=;
return;
}
build(l,mid-,mid);build(mid+,r,mid);
pushup(x);
//cout<<x<<' '<<c[x][0]<<' '<<c[x][1]<<' '<<sum[x]<<endl;
}
inline int find(int x,int k)
{
int l=c[x][],r=c[x][];
if(s[l]+==k)return x;
else if(s[l]>=k)return find(l,k);
else return find(r,k-s[l]-);
}
inline void split(int l,int r)
{
xx=find(rt,l);yy=find(rt,r);
splay(xx,rt);splay(yy,c[xx][]);
}
inline void print(int x)
{
if(!x)return;
//cout<<x<<' '<<c[x][0]<<' '<<c[x][1]<<"AAAAAAAAAAA"<<endl;
print(c[x][]);
cout<<(char)v[x];
print(c[x][]);
}
inline ull query(int l,int r)
{
split(l,r+);
//cout<<l<<' '<<r<<endl;
//cout<<l<<' '<<r<<' '<<c[y][0]<<' '<<sum[c[y][0]]<<' '<<v[c[y][0]]<<endl;
//print(c[yy][0]);cout<<endl;
//cout<<sum[c[yy][0]]<<endl;
return sum[c[yy][]];
} int main() { n=read();q=read();
hash[]=;
for1(i,maxn-)hash[i]=hash[i-]*(ull);
scanf("%s",st+);m=strlen(st+);
st[]=st[m++]='a';
build(,m+,);rt=id[(+m+)>>];
//cout<<id[2]<<' '<<id[3]<<endl;
while(q--)
{
char ch[];scanf("%s",ch);
//cout<<"AAAAAAAAAA"<<endl;
if(ch[]=='L')
{
int a=read(),b=read(),l=,r=s[rt]--b+;
while(l<=r)
{
int mid=(l+r)>>;
//cout<<l<<' '<<mid<<' '<<r<<endl;
if(query(a,a+mid-)==query(b,b+mid-))l=mid+;else r=mid-;
}
printf("%d\n",r);
}
else if(ch[]=='A')
{
int a=read();//cout<<a<<endl;
scanf("%s",st+);m=strlen(st+);
build(,m,);
split(a,a+);
fa[c[yy][]=id[(+m)>>]]=yy;
pushup(yy);pushup(xx);
}
else if(ch[]=='C')
{
int a=read(),b=read();
scanf("%s",st+);m=strlen(st+);
build(,m,);
split(a,b+);
fa[c[yy][]=id[(+m)>>]]=yy;
pushup(yy);pushup(xx);
}
else
{
int a=read(),b=read();
split(a,b+);
c[yy][]=;
pushup(yy);pushup(xx);
}
} return ; }

BZOJ2105: 增强型LCP的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. 第18章 图元文件_18.2 增强型图元文件(emf)(2)

    18.2.7 增强型图元文件的查看和打印程序 (1)传递EMF到剪贴板,剪贴板类型应为:CF_ENHMETAFILE (2)CopyEnhMetaFile用于复制图元文件 (3)剪贴板中的图元文件会自 ...

  3. 第18章 图元文件_18.2 增强型图元文件(emf)(1)

    18.2 增强型图元文件(emf) 18.2.1 创建并显示增强型图元文件的步骤 (1)创建:hdcEMF = CreateEnhMetaFile(hdcRef,szFilename,lpRect,l ...

  4. Java 增强型的for循环 for each

    Java 增强型的for循环 for each For-Each循环 For-Each循环也叫增强型的for循环,或者叫foreach循环. For-Each循环是JDK5.0的新特性(其他新特性比如 ...

  5. 黑马程序员——【Java高新技术】——JDK1.5新特性:静态导入、可变参数、增强型for循环、自动装箱拆箱、枚举

    ---------- android培训.java培训.期待与您交流! ---------- 一.静态导入 1.import和import static区别: (1)import 是导入一个类或某个包 ...

  6. 增强型for循环,用于遍历数组元素

    /** * */ package com.cn.u4; /** * @author Administrator *增强型for */ public class ZhengQiangFor { publ ...

  7. 【BZOJ】1014: [JSOI2008]火星人prefix(splay+hash+二分+lcp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1014 题意:支持插入一个字符.修改一个字符,查询lcp.(总长度<=100000, 操作< ...

  8. php版redis插件,SSDB数据库,增强型的Redis管理api实例

    php版redis插件,SSDB数据库,增强型的Redis管理api实例 SSDB是一套基于LevelDB存储引擎的非关系型数据库(NOSQL),可用于取代Redis,更适合海量数据的存储.另外,ro ...

  9. poj 2774 Long Long Message 后缀数组LCP理解

    题目链接 题意:给两个长度不超过1e5的字符串,问两个字符串的连续公共子串最大长度为多少? 思路:两个字符串连接之后直接后缀数组+LCP,在height中找出max同时满足一左一右即可: #inclu ...

随机推荐

  1. 数据库性能优化一:SQL索引一步到位

    SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开他的神秘面纱. 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引 ...

  2. php模板引擎

    http://baike.baidu.com/link?url=HmXfdJBv3zpCdnZPeaSmZmqDBHlyTBnz9Rmb5it-jf1_NLHfaku6_i8ssUYbnaTQEBD4 ...

  3. BCEC手动验证业务方法

    在每次割接或业务调整后手动执行并做好业务验证工作 一.研发区利用ansible手动执行巡检程序: 步骤1:登陆 10.254.3.4/opt/ansible 步骤2:手动执行 sh compute_c ...

  4. stack around the variable “XX” was corrupted

    晚上花了几个小时fix了这个恼人的BUG!“在变量XX周围的堆栈已损坏” 在网上找到的解释是: 把“project->配置属性->c/c++->代码生成->基本运行时检查 设置 ...

  5. v4l2简介

    V4L是linux内核中关于视频设备的子系统,为linux下的视频驱动提供了统一的接口,使应用程序可以使用统一的API操作不同的视频设备,简化视频系统的开发与维护 V4L2相比与V4L有更好的扩展性和 ...

  6. Java---Hibernate>>Can't create table './xxx/#sql-b2c_1a.frm' (errno: xxx)解决方法

    通用方案:删除相关表,重新生成. 1.关联表之间数据引擎不一致导致: 修改相关表的引擎设定,保持一致. 2.关联表索引字段的引用类型不一样(如A表关联字段是int,B表索引是char): 修改相关表的 ...

  7. css盒子模型、文档流、相对与绝对定位、浮动与清除模型

    一.CSS中的盒子模型 标准模式和混杂模式(IE).在标准模式下浏览器按照规范呈现页面:在混杂模式下,页面以一种比较宽松的向后兼容的方式显示.混杂模式通常模拟老式浏览器的行为以防止老站点无法工作. h ...

  8. jQuery设置checkbox全选(区别jQuery版本)

    jQuery设置checkbox全选在网上有各种文章介绍,但是为什么在我们用他们的代码的时候就没有效果呢? 如果你的代码一点错误都没有,先不要急着怀疑人家代码的正确性,也许只是人家跟你用的jQuery ...

  9. mysql中char与varchar的区别

    在建立数据库表结构的时候,为了给一个String类型的数据定义一个数据库的数据库类型,一般参考的都是char或者varchar,这两种选择有时候让人很纠结,今天想总结一下它们两者的区别,明确一下选择塔 ...

  10. css3 标题超过长度自动省略号

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...