Uva 11922 Splay】的更多相关文章

UVA 11922 题意: 有n个数1~n 操作a,b表示取出第a~b个数,翻转后添加到数列的尾部 输入n,m 输入m条指令a,b 输出最终的序列 代码: #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define Key_Value ch[ch[root][1]][0] ; int n,m; ],root,tot1; void Update_Rev(int r){…
题意: 1个1—n的排列,实现一下操作:将a—b翻转并移动至序列的最后. SOL: splay维护区间的裸题——不过平衡树的题目貌似都是裸的吧...就是看操作的复杂程度罢... 如何取区间呢,我们在splay中新增两个头尾结点,我们暂且把他叫做卫兵好了,永远把序列夹在中间——注意这个永远,我们在进行序列操作时便要维护并利用这个永远. 取序列在那个splay的线段树中已经讲过了,我们分离出一棵子树即可,如何插入呢.我们注意到要将这个点插入序列尾,它一定在尾卫兵与分离后序列最末结点之间.那么我们只要…
Splay(伸展树)实现可分裂与合并的序列 对于BST,除了Treap树之外,还有一种Splay的伸展树,他能快速的分裂与合并. 重要的操作是伸展操作,将一个指定的结点 x 旋转到根的过程. 分三种情况,一次单旋,两次同向单旋,两次反向旋转.可以手动模拟一下这个过程. 到这里,问题常常是将序列的第 k 个元素旋转到根. 首先,要知道的是伸展树里面v存的是什么,是节点的编号(下标).这样才能像 Treap实现名次树那样,很方便的找到左边第 k 个元素. //将序列左数第k个元素选择到根 void…
原题链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902 伸展树的区间翻转剪切... 如下: #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> ; struct Node{ int v, s, rev; Node *pre, *ch[]; inline , , Node *p =…
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18902 [思路] 伸展树+打标记. 用伸展树维护这个序列,使得能够提供快速的分裂与合并O(logn),利用打标记的方法处理区间翻转的问题. 需要注意的有: 1)在splay与print中都需要合适地调用pushdown下传标记. 2)Merge操作应该满足left中所有元素都比right中的元素小,这里的大小定义为序列位置的大小而不是键值v的大小. 3)因为me…
题目链接 题意:你的任务是根据m条指令改变排列{!,2,3,...,n}.每条指令(a,b)表示取出第a~b个元素,翻转后添加到排列的尾部.输出最终序列. 解法:splay对区间分裂合并翻转,模板题. 初学splay,代码写得有点挫,以后慢慢改~~ #include<bits/stdc++.h> using namespace std; struct Splay { ; ],siz[N],val[N],fa[N],tot,flip[N],n,m; int rel(int u) { ]==u;…
题意: 给一个序列,是从1~n共n个的自然数,接下来又m个区间,对于每个区间[a,b],从第a个到第b个从序列中分离出来,翻转后接到尾部.输出最后的序列. 思路: 这次添加了Split和Merge两个基本操作,还有个比较困难的翻转操作.翻转操作只需要将需要翻转的序列独立成树,给根加上翻转标记之后再直接插到另外由前后两棵树组成的树上.但是在做一些操作的时候可能会遇到已经标记了翻转的子树,比如splay时,如果不顾flip标记,直接带flip标记的点伸展到根,会就会跟其他没有标记的节点混合了,而一个…
题意:根据m条指令改变排列1 2 3 4 … n ,每条指令(a, b)表示取出第a~b个元素,反转后添加到排列尾部 分析:用一个可分裂合并的序列来表示整个序列,截取一段可以用两次分裂一次合并实现,粘贴到末尾可以用一次合并实现. 翻转可以采用在每个结点上做标记的方法,flip = 1意味着将这棵子树翻转,可以类似线段树用一个pushdown()实现标记向下传递. 可以发现当前排列就是伸展树的中序遍历序列.中序遍历打印结果即可. 注意代码中设置了虚拟首结点0的技巧. 代码如下: #include…
上次ZOJ月赛碰到一个题目要求对序列中的某个区间求gcd,并且还要随时对某位数字进行修改 插入 删除,当时马上联想到线段树,但是线段树不支持增删,明显还是不可以的,然后就敲了个链表想暴力一下,结果TLE.那天回来后搜了下题解,发现大家都在说平衡树 Splay,就好好学了下,这玩意还是挺难学的,我看了好久.最后还是从网上找了三篇论文打印了下,趁着TCG讲数据库的时候(这课真的好催眠)好好看了下,才搞清楚基本的Splay操作 这是第一道Splay题目,基本上是照着模板敲出来的,没办法,第一次学,好多…
第一棵伸展树,各种调试模板……TVT 对于 1 n 这种查询我处理的不太好,之前序列前后没有添加冗余节点,一直Runtime Error. 后来加上冗余节点之后又出了别的状况,因为多了 0 和 n+1 这两个节点,并且每次截取翻转添加到序列最后,因此无法确定 n+1 这个节点在序列的哪个位置. 比如(括号中的为添加的冗余节点): (0) 1 2 3 4 5 (6) 我把[3,4]截取翻转添加到序列尾部,会变成这样: (0)1 2 5 (6)4 3 此时我如果再希望截取[3,4],期望的结果应该是…
splay的题: 学习白书上和网上的代码敲的: #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; int n,m; struct node { node *ch[]; int s,v; int flip; node(int v):v(v) { ch[]=ch[]=NULL; s=; flip=; } void ma…
Description Write a program to transform the permutation 1, 2, 3,..., n according to m instructions. Each instruction (a, b) means to take out the subsequence from the a-th to the b-th element, reverse it, then append it to the end. Input There is on…
题意:一开始给出一个序列\(1,2...n\),然后\(m\)次操作,每次把\([l,r]\)翻转并且拼接到序列的后面,求最后形成的序列 打个pushdown标记就好 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<string> #inc…
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2202  Solved: 1226[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次…
今天跟着zcg大神学了一发fhq_treap 发现在维护区间问题上fhq_treap不仅思维量小,而且代码量更小 是Splay的不错的替代品,不过至今还是有一些问题不能很好的解决 譬如查询某个数在序列中的第几个位置QAQ fhq_treap的核心是split和merge可以logn的完成区间的分裂和合并 由于没有旋转所以可以支持可持久化 cojs 2314 可持久化fhq_treap的裸题,直接上代码 每次merge和split的时候新建一条链上的节点就可以啦 #include<cstdio>…
题意:给定一个长度为n的01串,你的任务是依次执行如表所示的m条指令: 1 p c 在第p个字符后插入字符,p = 0表示在整个字符串之前插入2 p 删除第p个字符,后面的字符往前移3 p1 p2反转第p1到第p2个字符4 p1 p2输出从p1开始和p2开始的两个后缀的LCP. 析:对于前三个操作,splay 很容易就可以解决,但是对于最后一个操作,却不是那么容易,因为这是动态的,所以我们也要维护一个可以动态的,这就可以用Hash来解决,由于要翻转,所以要维护两个,一个正向的,一个反向的.在操作…
题意:给n个坐标.一个坐标(x,y)若有无存在的坐标满足x1<x && y1<=y  或  x1<=x && y1<y 时,此坐标(x,y)是就是有优势的.在给每一个坐标之后,立刻输出当前有优势的坐标有多少个. 思路:Set可以做,但是我用Splay树实现也不难.观察题意中的不等式发现,一个点(x,y)的左下方不能有点(相当于跟(0,0)组成的矩形中不能有其他点,除了(x,y)之外),但是若有相同的点的存在,这些相同点都是优势点. 用Splay维护剩…
#include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <vector> using namespace std; typedef unsigned long long ull; ; ; ull xp[maxn]; int n, m; struct Node { Node* ch[]; int r, v, s; int val;…
Jewel Magic UVA - 11996 这是一道用splay/非旋treap做的题(这里用的是非旋treap) 1/2/3是splay/非旋treap的常规操作.对于操作4,可以用哈希法求LCP.记hash(i,L)为子串[i,i+L-1](即第i个开始的L个)的hash值.记s[i]为序列第i位(编号从1开始),n为序列长度 如果通过某种方式做到能在O(logn)时间内取出一段子串的hash值,那么二分答案(即LCP长度x),可以在O(logn)时间内判一个x是否合法(如果hash(l…
1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discuss] Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个…
Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列.这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格.光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间.文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程…
来自wjmzbmr的splay模板 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; + ; ; struct Node { Node*ch[], *p; int size, val, mx; int add; bool rev; Node() { size = ; val = mx = -INF; add = ; } bool d() { ]; } void set…
查最小值,删除,翻转... 显然splay啊... #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 200005 #define inf 0x3f3f3f3f using namespace std; int n; ], fa[N]; int a[N]; int mn[N],zhi[N],size[N]; void push_up(int…
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数 接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n Output 输出一行n个数字,表示原始序列经过m次变换后的结果 Sample Input 5 3 1 3…
人生第一道splay不出所料是一道裸题,一道水题,一道2k代码都不到的题 #include <cstdio> ,n,p,q; ],c[][],size[],sp[]; void rot(int x) { ]==x); size[y]=size[c[y][k]]+size[c[x][k]]+;size[x]=size[c[x][!k]]+size[y]+; c[y][!k]=c[x][k];fa[c[y][!k]]=y; fa[x]=fa[y];]==y]=x; c[x][k]=y;fa[y]=…
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5…
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6243  Solved: 2007[Submit][Status][Discuss] Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字符 m a d a m i m a d…
1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 12278  Solved: 3880[Submit][Status][Discuss] Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格.任何时刻数列中最多含有500 000个数,…
Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3913    Accepted Submission(s): 1717 Problem Description Somewhere deep in the Czech Technical University buildings, there are labora…
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3595  Solved: 2029[Submit][Status][Discuss] Description   您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列…