bzoj1014火星人
...强迫症终于A了这道题 bzoj前30道全A指日可待
splay维护这个结点控制的字符串的hash值
每次旋转重新算一遍就可以了
查询的时候跑一个二分
讲起来很简单但是还是调了1h才调对了splay
把main写完饺子都凉了
没写过几次平衡树 常数写的奇大 能递归的我都递归了。。。
字符串哈希因为过于Naive只会用自然溢出。。。
但是1A了
家里的电脑有写好的read和write
我竟然忘了。。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#define ll unsigned long long
#define pi 3.14
#define eps 1e-9
#define inf 2147483233
#define m(a) memset(a,0,sizeof(a))
#define M(a) memset(a,127,sizeof(a))
#define REP(i,m,n) for(int i=1;i<=n;i++)
#define DWN(i,n,m) for(int i=n;i>=1;i++)
#define lowbit(x) x&(-x)
using namespace std;
int n;
inline int read()
{
int x=,f=;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=*x+ch-'';ch=getchar();}
return x*f;
}
inline void write(int x)
{
int num=;
char buf[];
while(x)buf[++num]=(x%)+'',x/=;
while(num)putchar(buf[num--]);
putchar('\n');
}
ll powe[];
void makepow()
{
int i;
for(powe[]=,i=;i<;i++)powe[i]=powe[i-]*;
}
const int maxn=;
char str[maxn];
struct SplayTree
{
int rt,Size;
int son[maxn][],f[maxn],size[maxn];
ll val[maxn],hsh[maxn];
char s[maxn];
inline void pushup(int x){size[x]=size[son[x][]]+size[son[x][]]+;hsh[x]=hsh[son[x][]]+powe[size[son[x][]]]*s[x]+powe[size[son[x][]]+]*hsh[son[x][]];}
inline void Rotate(int x,int type)
{
int y=f[x];
son[y][!type]=son[x][type];
f[son[x][type]]=y;
f[x]=f[y];
if(f[x])son[f[y]][son[f[y]][]==y]=x;
son[x][type]=y;
f[y]=x;
size[x]=size[y],hsh[x]=hsh[y];
pushup(y);
}
inline void splay(int x,int goal)
{
while(f[x]!=goal)
{
if(f[f[x]]==goal)
{
if(son[f[x]][]==x)Rotate(x,);
else Rotate(x,);
}
else
{
int y=f[x],z=f[y];
if(son[z][]==y)
{
if(son[y][]==x)Rotate(y,),Rotate(x,);
else Rotate(x,),Rotate(x,);
}
else
{
if(son[y][]==x)Rotate(y,),Rotate(x,);
else Rotate(x,),Rotate(x,);
}
}
}
if(goal==) rt=x;
}
inline int rank(int x,int k)
{
if(k<=size[son[x][]]) return rank(son[x][],k);
else if(k==size[son[x][]]+) return x;
else return rank(son[x][],k-size[son[x][]]-);
}
inline int build(int l,int r,int id)
{
if(l>r)return ;
int x=++Size,mid=(l+r)>>;
f[x]=id;
s[x]=str[mid];
son[x][]=build(l,mid-,x);
son[x][]=build(mid+,r,x);
pushup(x);
return x;
}
inline void insert(int k,char val)
{
int x=rank(rt,k),y=rank(rt,k+);
splay(x,),splay(y,x);
s[++Size]=val;
f[Size]=y,son[y][]=Size;
pushup(Size);
pushup(y);
pushup(x);
}
inline void change(int k,int val)
{
int x=rank(rt,k);
splay(x,);
s[x]=val;
pushup(x);
}
inline int bisearch(int kx,int ky)
{
int l=,r=n,mid;
while(l<=r)
{
mid=l+r>>;
if(ky+mid>n+)
{
r=mid-;
continue;
}
int x=rank(rt,kx-),y=rank(rt,kx+mid);
splay(x,),splay(y,x);
ll temp=hsh[son[y][]];
x=rank(rt,ky-),y=rank(rt,ky+mid);
splay(x,),splay(y,x);
if(temp==hsh[son[y][]])l=mid+;
else r=mid-;
}
return r;
}
}splay;
int main()
{
int m,i,j,k,x,y;
char op[],val[];
scanf("%s%d",str+,&m);
makepow();
n=strlen(str+);
splay.rt=splay.build(,n+,);
for(i=;i<=m;i++)
{
scanf("%s",op);
if(op[]=='I')
{
scanf("%d%s",&x,val);
splay.insert(x+,val[]);
n++;
}
else if(op[]=='R')
{
scanf("%d%s",&x,val);
splay.change(x+,val[]);
}
else
{
scanf("%d%d",&x,&y);
if(x>y) swap(x,y);
if(x!=y)
printf("%d\n",splay.bisearch(x+,y+));
else
printf("%d\n",n-x+);
}
}
return ;
}
bzoj1014火星人的更多相关文章
- 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树
!前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...
- BZOJ1014火星人prefix Splay維護序列 + 字符串哈希
@[Splay, 哈希] Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:\(madamimadam\), 我们将这个字符串的各个字符予以标号 ...
- BZOJ1014 火星人的prefix
火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字 ...
- bzoj1014 火星人 (hash+splay+二分答案)
求公共前缀的问题可以用hash+二分来解决,但这个是动态的,所以我们用平衡树来维护区间的hash值 复杂度$O(mlog^2n)$ #include<bits/stdc++.h> #def ...
- bzoj1000~1025
以后还是这样 25道题一起发 看着爽 noip失利之后发粪涂墙 刷了一波bzoj 题解: bzoj1000 A+B问题 这题不同的人有不同的写法,我写了个线段树套Treap,应该还是挺简单的 但是看别 ...
- [BZOJ1014][JSOI2008]火星人prefix
[BZOJ1014][JSOI2008]火星人prefix 试题描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字 ...
- 【BZOJ1014】火星人(Splay,哈希)
[BZOJ1014]火星人(Splay,哈希) 题面 BZOJ 题解 要动态维护这个串,一脸的平衡树. 那么用\(Splay\)维护这个哈希值就好了. 每次计算答案的时候二分+Splay计算区间哈希值 ...
- BZOJ1014 JSOI2008 火星人prefix 【非旋转Treap】*
BZOJ1014 JSOI2008 火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符 ...
- 【bzoj1014】: [JSOI2008]火星人prefix 平衡树-字符串-hash-二分
[bzoj1014]: [JSOI2008]火星人 用平衡树维护字符串的hash 然后询问的时候二分一下就好了 /* http://www.cnblogs.com/karl07/ */ #includ ...
随机推荐
- 【BZOJ4016】[FJOI2014]最短路径树问题 最短路径树+点分治
[BZOJ4016][FJOI2014]最短路径树问题 Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径 ...
- linux字符集查看与设置
linux字符集查看与设置 命令:locale -a 查看本地的字符集 locale -m 查看所有支持的字符集 查看当前默认设置 echo $LANG 记录系统默认使用 ...
- gIt 常用 操作
git提交代码流程git status -- 查看当前仓库状态git add -- 添加到临时仓库git commit -m '注释' -- 添加到临时仓库git status -- 查看当前仓库 ...
- vue 指令系统的使用
所谓指令系统,大家可以联想咱们的cmd命令行工具,只要我输入一条正确的指令,系统就开始干活了. 在vue中,指令系统,设置一些命令之后,来操作我们的数据属性,并展示到我们的DOM上. OK,接下来我们 ...
- Django与Vue语法冲突问题完美解决方法
当我们在django web框架中,使用vue的时候,会遇到语法冲突. 因为vue使用{{}},而django也使用{{}},因此会冲突. 解决办法1: 在django1.5以后,加入了标签: {% ...
- 说说JavaScript 中的new吧
在其他语言中,new操作符都是用来实例化创建一个对象的,JavaScript 中同样如此,但是它又有一些不同.为了说清楚这个问题我们先来看一下JavaScript 中的类.原型.原型链.继承这些概念吧 ...
- jquery链式语法
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- iOS block 闭包的学习
iOS 闭包 学习 理解: 1 . 闭包外界无法访问内部变量 ,它是一个独立的代码块. 2 . 闭包可以作为 一个方法 ,甚至局部变量 全局 变量 3 . 闭包 是一种引用类型 注 ...
- 面试问题(HTML和CSS方面)
1 IE/Win的 HasLayout 2 浮动 float 的定义.float后元素的display属性会发生改变吗?3 CSS 3.0.CSS2.1 中被现代浏览器应用了的规则有哪些?4 父元素定 ...
- 第二十三篇、IO多路复用 二
基于IO多路复用实现socket的连接 下面流程:1.先创建列表,让自己的socket对象传入,然后遍历select第一个参数2.客户端连接,那么客户端socket就传入到了列表里面,3.遍历,接收客 ...