【算法】splay

【题解】对于每个结点维护其子树串的hash值,前面为高位,后面为低位。

sum[x]=sum[L]*base[s[R]+1]+A[x]*base[s[R]]+sum[R],其中sum为哈希,base为乘权,A为数值(即字符)。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,inf=0x3f3f3f3f,bases=;
int f[maxn],t[maxn][],s[maxn],A[maxn],a[maxn],sz=,root,n;
unsigned long long sum[maxn],a_,b_,b[maxn];
int Node(int fa,int num)
{
sz++;
f[sz]=fa;t[sz][]=t[sz][]=;
s[sz]=;A[sz]=sum[sz]=num;
return sz;
}
void count(int x)
{
s[x]=s[t[x][]]++s[t[x][]];
sum[x]=sum[t[x][]]*b[s[t[x][]]+]+1ull*A[x]*b[s[t[x][]]]+sum[t[x][]];
}
void build(int fa,int &x,int l,int r)
{
if(l>r)return;
int mid=(l+r)>>;
x=Node(fa,a[mid]);
build(x,t[x][],l,mid-);
build(x,t[x][],mid+,r);
count(x);
}
void rotate(int x)
{
int k=x==t[f[x]][];
int y=f[x];
t[y][k]=t[x][!k];f[t[x][!k]]=y;
if(f[y])t[f[y]][y==t[f[y]][]]=x;f[x]=f[y];f[y]=x;
t[x][!k]=y;
sum[x]=sum[y];s[x]=s[y];
count(y);
}
void splay(int x,int r)
{
for(int fa=f[r];f[x]!=fa;)
{
if(f[f[x]]==fa){rotate(x);return;}
int X=x==t[x][],Y=f[x]==t[f[f[x]]][];
if(X^Y)rotate(x),rotate(x);
else rotate(f[x]),rotate(x);
}
}
void find(int &x,int k)
{
for(int i=x;i;)
{
if(k<=s[t[i][]]){i=t[i][];continue;}
if(k==s[t[i][]]+){splay(i,x);x=i;return;}
k-=s[t[i][]]+;i=t[i][];
}
}
bool work(int x,int y,int longs)
{
if(x+longs->n||y+longs->n)return ;
find(root,x);find(t[root][],longs+);
a_=sum[t[t[root][]][]];
find(root,y);find(t[root][],longs+);
b_=sum[t[t[root][]][]];
if(a_==b_)return ;
return ;
}
void ask()
{
int x,y;
scanf("%d%d",&x,&y);
int l=,r=maxn;
while(l<r)
{
int mid=(l+r)>>;
if(work(x,y,mid))l=mid+;
else r=mid;
}
printf("%d\n",l-);
}
void repair()
{
int x;char c;
scanf("%d %c",&x,&c);
find(root,x+);
A[root]=c-'a'+;
count(root);
}
void insert()
{
n++;
int x;char c;
scanf("%d %c",&x,&c);
find(root,x+);find(t[root][],);
int y=Node(t[root][],c-'a'+);
t[t[root][]][]=y;
f[y]=t[root][];
count(t[root][]);
count(root);
}
char str[maxn];
int main()
{
scanf("%s",str+);
n=strlen(str+);
for(int i=;i<=n;i++)a[i]=str[i]-'a'+;
b[]=;
for(int i=;i<=maxn;i++)b[i]=b[i-]*bases;
root=a[]=a[n+]=;
build(,root,,n+);
int m;
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%s",str);//不要用%c会读空格,用%s读到空格会停。
if(str[]=='Q')ask();
if(str[]=='R')repair();
if(str[]=='I')insert();
}
return ;
}

update:现在已改用fhq-treap代替splay。

【BZOJ】1014 [JSOI2008]火星人prefix的更多相关文章

  1. BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6243  Solved: 2007[Submit] ...

  2. BZOJ 1014: [JSOI2008]火星人prefix Splay+二分

    1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...

  3. bzoj 1014: [JSOI2008]火星人prefix hash && splay

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3154  Solved: 948[Submit][ ...

  4. 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4164  Solved: 1277[Submit] ...

  5. BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )

    用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...

  6. BZOJ 1014 [JSOI2008]火星人prefix (Splay + Hash + 二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8112  Solved: 2569[Submit] ...

  7. [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】

    题目链接:BZOJ - 1014 题目分析 求两个串的 LCP ,一种常见的方法就是 二分+Hash,对于一个二分的长度 l,如果两个串的长度为 l 的前缀的Hash相等,就认为他们相等. 这里有修改 ...

  8. BZOJ 1014: [JSOI2008]火星人prefix

    Sol Splay+Hash+二分答案. 用Splay维护Hash,二分答案判断. 复杂度 \(O(nlog^2n)\) PS:这题调了两个晚上因为没开long long.许久不写数据结构题感觉写完整 ...

  9. bzoj 1014 [JSOI2008]火星人prefix(splay+hash)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 给定一个字符串,要求提供修改一个字符,插入一个字符,查询两个后缀LCP ...

  10. bzoj 1014 [JSOI2008]火星人prefix——splay+哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...

随机推荐

  1. ZooKeeper server &&client

    写了一个关于zookeepeer应用的简单demo 服务端定时的向zookeeper集群注册,客户端监听zookeeper服务节点变化,一旦变化,立刻响应,更新服务端列表 服务端代码: #includ ...

  2. iOS- 利用UIImageView自己整了个不会说话的汤姆猫

    1.实现思路 先说说我实现它的主要思路,很简单,主要利用UIImageView连续动画播放,和按钮的点击事件,就可以完成了这么一个简单的不会说话的汤姆猫. 2.实现细节 2.1.加载本地字典里保存的本 ...

  3. iOS- 多线程技术的概述及优点

    1.概述 在iOS开发中: •耗时操作,例如网络图片.视频.歌曲.书籍等资源下载 •游戏中的声音播放   我们可以利用多线程: •充分发挥多核处理器的优势,并发(同时执行)执行任务让系统运行的更快.更 ...

  4. 使用cookies模拟登陆

    http://blog.csdn.net/a1099439833/article/details/51918955 使用cookies会话跟踪,保持cookies访问,对于cookies会失效的问题可 ...

  5. 3ds Max学习日记(六)

      到了周六就不想再忙实验室的活了,于是玩了一下3ds max,第5和第6章每章都只有4个视频,于是就一起弄完了,什么网格建模,曲面建模啥的,nurbs啥的. 附上今日的劳动成果:   叉子(用长方体 ...

  6. node 第一天

    在开发的过程中,几乎不可能一次性就能写出毫无破绽的程序,断点调试代码是一个普遍的需求. 作为前端开发工程师,以往我们开发的JavaScript程序都运行在浏览器端,利用Chrome提供的开发者工具就可 ...

  7. Ubuntu安装配置JDK、Tomcat、SVN服务器

    一.配置jdk 1.下载JDK http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html 注:笔者是直 ...

  8. using指令含义

    using指令作用: 就是导入命名空间,这样你比如用StringBuilder类,就不用System.Text.StringBuilder builder = new System.Text.Stri ...

  9. 使用户浏览器添加没有的字体@font-face

    @font-face的用法 @font-face { font-family: 'MyWebFont'; src: url('webfont.eot'); /* IE9 Compat Modes */ ...

  10. bzoj1835[ZJOI2010]基站选址

    主席树+决策单调,重写一遍比之前短多了……题解:http://www.cnblogs.com/liu-runda/p/6051422.html #include<cstdio> #incl ...