...强迫症终于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火星人的更多相关文章

  1. 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树

    !前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...

  2. BZOJ1014火星人prefix Splay維護序列 + 字符串哈希

    @[Splay, 哈希] Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:\(madamimadam\), 我们将这个字符串的各个字符予以标号 ...

  3. BZOJ1014 火星人的prefix

    火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字 ...

  4. bzoj1014 火星人 (hash+splay+二分答案)

    求公共前缀的问题可以用hash+二分来解决,但这个是动态的,所以我们用平衡树来维护区间的hash值 复杂度$O(mlog^2n)$ #include<bits/stdc++.h> #def ...

  5. bzoj1000~1025

    以后还是这样 25道题一起发 看着爽 noip失利之后发粪涂墙 刷了一波bzoj 题解: bzoj1000 A+B问题 这题不同的人有不同的写法,我写了个线段树套Treap,应该还是挺简单的 但是看别 ...

  6. [BZOJ1014][JSOI2008]火星人prefix

    [BZOJ1014][JSOI2008]火星人prefix 试题描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字 ...

  7. 【BZOJ1014】火星人(Splay,哈希)

    [BZOJ1014]火星人(Splay,哈希) 题面 BZOJ 题解 要动态维护这个串,一脸的平衡树. 那么用\(Splay\)维护这个哈希值就好了. 每次计算答案的时候二分+Splay计算区间哈希值 ...

  8. BZOJ1014 JSOI2008 火星人prefix 【非旋转Treap】*

    BZOJ1014 JSOI2008 火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符 ...

  9. 【bzoj1014】: [JSOI2008]火星人prefix 平衡树-字符串-hash-二分

    [bzoj1014]: [JSOI2008]火星人 用平衡树维护字符串的hash 然后询问的时候二分一下就好了 /* http://www.cnblogs.com/karl07/ */ #includ ...

随机推荐

  1. lua(仿类)

    Account = { balance = } function Account:deposit(v) self.balance = self.balance + v end function Acc ...

  2. 九度OJ 1250:矩阵变换 (矩阵运算)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:95 解决:47 题目描述: 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一, 现给出一正数矩 ...

  3. TensorFlow_action

    安装TensorFlow  包依赖 C:\Users\sas> pip3 install --upgrade tensorflow Collecting tensorflow Downloadi ...

  4. 【python】-- 文件操作

    一.概述 我们工作中需要经常操作文件,下面就讲讲如何用Python操作文件 1.文件操作的流程: 打开文件,得到文件句柄赋值给一个变量 通过文件句柄,对文件进行操作 关闭文件 #获取文件句柄 f = ...

  5. Meeting-in-the-Middle (LA 2965)

    Meeting-in-the-Middle,又称“中途相遇法”.准确地说,它只是一种策略. 顺便说一下,这个算法真的很冷门! 结合这道题来讨论一下吧:LA 2965.ε(┬┬﹏┬┬)3 因为博主的英文 ...

  6. 我的Android进阶之旅------>Android 标签的用法

    布局资源文件的根节点可以使用容器控件(如LinearLayout.FrameLayout等),也可以使用非容器控件(如:EditText.TextView等).对于非容器控件,只能在非容器控件标签中放 ...

  7. Bootstrap第3天

    Bootstrap第3天 图片样式 .img-responsive:直接为图片添加该样式,可以实现响应式图片. .center-block:图片居中样式,而不能使用text-center样式. 图片形 ...

  8. nginx-gridfs的安装

    mongodb中gridfs适合存放视频和高清图片等等超大文件(小的文件建议不要存在mongodb中): 下面是在centos下配置nginx来訪问mongodb中的mp4文件: 1:安装nginx- ...

  9. Tensorflow官方文档中文版——第一章

    第一示例: import tensorflow as tf import numpy as np x_data=np.float32(np.random.rand(,))#随机输入 y_data=np ...

  10. awk 字符串函数

    awk 提供了许多强大的字符串函数,见下表: awk 内置字符串函数 gsub(r,s) 在整个 $0 中用 s 替代 r gsub(r,s,t) 在整个 t 中用 s 替代 r index(s,t) ...