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可以用奇技淫巧来简单合并...调了一下午终于幡然醒悟...于是就只好一个一个慢慢插...什么启发式合 ...
随机推荐
- Jenkins系列-Jenkins通过Publish over SSH插件实现远程部署
配置ssh免秘钥登录 安装Publish over SSH插件 插件使用官网:https://wiki.jenkins.io/display/JENKINS/Publish+Over+SSH+Plug ...
- python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
#vi /etc/ld.so.conf.d/python2.7.conf 加入/usr/local/python27/lib 保存退出后执行 #ldconfig
- Binding自动侦听
WPF的强大之一就是数据绑定,Binding是数据桥梁,它的两端是分别是源(Source)和目标(Target),一个简单的类的属性值发生变化,会自动反映在UI界面上,这个属性就是Binding的Pa ...
- RT-thread 设备驱动组件之SPI设备
本文主要介绍RT-thread中的SPI设备驱动,涉及到的文件主要有:驱动框架文件(spi_dev.c,spi_core.c,spi.h),底层硬件驱动文件(spi_hard.c,spi_hard.h ...
- 路由分发原则 get最终传递给get post最终传递给post
- BZOJ4000 TJOI2015棋盘(状压dp+矩阵快速幂)
显然每一行棋子的某种放法是否合法只与上一行有关,状压起来即可.然后n稍微有点大,矩阵快速幂即可. #include<iostream> #include<cstdio> #in ...
- Android 4.0源码结构
Android 4.0 |-- Makefile |-- bionic (bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等 ...
- 转:浅谈深度学习(Deep Learning)的基本思想和方法
浅谈深度学习(Deep Learning)的基本思想和方法 参考:http://blog.csdn.net/xianlingmao/article/details/8478562 深度学习(Deep ...
- [bzoj4391] [Usaco2015 dec]High Card Low Card 贪心 线段树
---题面--- 题解: 观察到以决策点为分界线,以点数大的赢为比较方式的游戏都是它的前缀,反之以点数小的赢为比较方式的都是它的后缀,也就是答案是由两段答案拼凑起来的. 如果不考虑判断胜负的条件的变化 ...
- POJ2728:Desert King——题解
http://poj.org/problem?id=2728 题目大意:求一棵生成树使得路费用和/路长之和最小(路的费用是两端点的高度差) 最小比率生成树. 我们还是01分数规划的思想将边权变为路费用 ...