bzoj 2258 splay
类似于1014,用splay维护这个序列,维护每个节点为根的子树的hash值,对于一个询问二分答案判断就行了。
反思:询问的时候因为是原序列的x,y,所以开始的时候直接splay(x-1)了,后来发现这是不对的,因为可能在x前插入一些东西,所以需要麻烦些,先splay(x),然后提出来右端点为size[son[rot][0]]+1+len,然后再splay(find(size[son[rot][0]]+1))。
/**************************************************************
Problem: 2258
User: BLADEVIL
Language: C++
Result: Accepted
Time:7904 ms
Memory:3640 kb
****************************************************************/
//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010
using namespace std;
char s[maxn];
int fac[maxn],key[maxn],num,rot,son[maxn][],father[maxn],size[maxn],hash[maxn];
void update(int x) {
if (!x) return ;
hash[x]=hash[son[x][]]+(key[x]+hash[son[x][]]*)*fac[size[son[x][]]];
size[x]=size[son[x][]]+size[son[x][]]+;
}
int build(int l,int r) {
int mid=l+r>>,left=,right=;
if (mid<r) right=build(mid+,r);
if (mid>l) left=build(l,mid-);
father[left]=father[right]=mid;
son[mid][]=left; son[mid][]=right;
update(mid);
return mid;
}
void rotate(int x,int &rot) {
int y=father[x],z=father[y];
int p=(son[y][]==x),q=p^;
if (y==rot) rot=x; else if (son[z][]==y) son[z][]=x; else son[z][]=x;
father[x]=z; father[y]=x; father[son[x][q]]=y;
son[y][p]=son[x][q]; son[x][q]=y;
update(y);
}
void splay(int x,int &rot) {
while (x!=rot) {
int y=father[x],z=father[y];
if (y!=rot)
if ((son[y][]==x)^(son[z][]==y)) rotate(x,rot); else rotate(y,rot);
rotate(x,rot);
}
update(x);
}
int find(int x) {
int t=rot;
while () {
if (size[son[t][]]+==x) return t; else
if (size[son[t][]]+>x) t=son[t][]; else
if (size[son[t][]]+<x) x-=size[son[t][]]+,t=son[t][];
}
}
bool judge(int x,int y,int len) {
if (len==) return key[x+]==key[y+];
int p=x+; splay(p,rot);
int q=find(size[son[rot][]]++len);
splay(find(size[son[rot][]]),rot); splay(q,son[rot][]);
int a1=hash[son[q][]];
p=y+; splay(p,rot);
q=find(size[son[rot][]]++len);
splay(find(size[son[rot][]]),rot); splay(q,son[rot][]);
int a2=hash[son[q][]];
return a1==a2;
}
int main() {
scanf("%s",s); num=strlen(s);
fac[]=; for (int i=;i<maxn;i++) fac[i]=fac[i-]*;
for (int i=;i<=num+;i++) key[i]=s[i-]-'a'+; num+=;
rot=build(,num);
int task; scanf("%d",&task);
while (task--) {
int x,y;
scanf("%s",s);
if (s[]=='Q') {
scanf("%d%d",&x,&y);
if (x>y) swap(x,y);
splay(y+,rot);
int l=,r=size[son[rot][]],mid,ans=;
while (l<=r) {
mid=l+r>>;
if (judge(x,y,mid)) ans=mid, l=mid+; else r=mid-;
}
printf("%d\n",ans);
} else
if (s[]=='I') {
scanf("%s%d",s,&x);
x=(x>num-)?num:x;
key[++num]=s[]-'a'+;
int p=find(x); splay(p,rot);
int q=find(x+); splay(q,son[rot][]);
father[num]=q; son[q][]=num;
splay(num,rot);
}
}
return ;
}
bzoj 2258 splay的更多相关文章
- bzoj 1269 bzoj 1507 Splay处理文本信息
bzoj 1269 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1269 大致思路: 用splay维护整个文本信息,splay树的中序遍历即为 ...
- bzoj 3506 && bzoj 1552 splay
查最小值,删除,翻转... 显然splay啊... #include<iostream> #include<cstdio> #include<algorithm> ...
- bzoj 1014 splay维护hash值
被后缀三人组虐了一下午,写道水题愉悦身心. 题很裸,求lcq时二分下答案就行了,写的不优美会被卡时. (写题时精神恍惚,不知不觉写了快两百行...竟然调都没调就A了...我还是继续看后缀自动机吧... ...
- bzoj 1503 splay
因为是整体加减,所以直接记录在外面. #include<iostream> #include<cstdio> #include<cstring> #include& ...
- bzoj 3224 splay模板题4
再刷水题我就废了... #include<iostream> #include<cstdio> #include<algorithm> #include<cs ...
- bzoj 3223 splay模板题3
水题...貌似理解splay怎么维护数列了... 每个点维护一个size,它的位置就是它的size,区间翻转的话可以打标记,find的时候push_down,交换左右子树. #include<i ...
- bzoj 1208 splay模板题2
自己yy了找前驱和后继,学了学怎么删除...(反正就是练模板) #include<iostream> #include<cstdio> #include<cstring& ...
- bzoj 1588 splay模板题
用晚自习学了一下splay模板,没想象中那么难,主要是左旋和右旋可以简化到一个函数里边,减少代码长度... #include<iostream> #include<cstdio> ...
- BZOJ 2733 & splay的合并
题意: 带权联通块,添边与查询联通块中第k大. SOL: splay合并+并查集. 我以为splay可以用奇技淫巧来简单合并...调了一下午终于幡然醒悟...于是就只好一个一个慢慢插...什么启发式合 ...
随机推荐
- MySQL加密算法
1.不可逆加密: PASSWORD(),ENCRYPT(,),MD5(),SHA5(). 2.可逆的加密算法: ENCODE(,) DECODE(,):加密解密字符串.该函数有两个参数:被加密或解 ...
- Python使用ElementTree美化XML格式
Python中使用ElementTree可以很方便的处理XML,但是产生的XML文件内容会合并在一行,难以看清楚. 如下格式: <root><aa>aatext<cc&g ...
- java 字符串—数字常用处理
// 判断一个字符串是否都为数字 public boolean isDigit(String strNum) { return strNum.matches("[0-9]{1,}" ...
- [C/C++] 结构体存储问题
64位操作系统,不同类型变量对应的字节数为: char : 1个字节 char*(即指针变量) : 8个字节 //32位占4个字节 short int : 2个字节 int : 4个字节 unsign ...
- [OS] CPU调度
调度准则 为了比较CPU调度算法,分析员提供了许多准则,用于比较的特征对确定最佳算法有很大影响.这些准则包括: ·CPU使用率:需要使CPU尽可能忙. ·吞吐量:一个时间单元内完成进程的数量. ·周转 ...
- 深入理解java内置锁(synchronized)和显式锁(ReentrantLock)
多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两种同步方式.显式锁是JDK1.5引入的,这两种锁有什么异同呢? ...
- 在a标签的href用户#name 的可以实现页面 上下跳转
- 【bzoj1707】[Usaco2007 Nov]tanning分配防晒霜 贪心+Treap
题目描述 奶牛们计划着去海滩上享受日光浴.为了避免皮肤被阳光灼伤,所有C(1 <= C <= 2500)头奶牛必须在出门之前在身上抹防晒霜.第i头奶牛适合的最小和最 大的SPF值分别为mi ...
- Luogu1041 NOIP2003传染病控制(搜索)
暴搜加个最优性剪枝即可.一直觉得正式比赛出这种不能一眼看出来暴搜就行了的搜索题的出题人都是毒瘤. #include<iostream> #include<cstdio> #in ...
- html的body内标签之超链接
一,先来个简单的练练手,target="_blank" 的作用是在新的tab中打开页面.href 是超链接的意思. <!DOCTYPE html> <html l ...