这题写起来真累.. 名次树就是多了一个附加信息记录以该节点为根的树的总结点的个数,由于BST的性质再根据这个附加信息,我们可以很容易找到这棵树中第k大的值是多少. 所以在这道题中用一棵名次树来维护一个连通分量. 由于图中添边比较方便,用并查集来表示连通分量就好了,但是删边不太容易实现. 所以,先把所有的边删去,然后逆序执行命令.当然,C命令也要发生一些变化,比如说顺序的情况是从a变成b,那么逆序执行的话应该就是从b变成a. 最后两棵树的合并就是启发式合并,把节点数少的数并到节点数多的数里去. #…
离线做法,逆序执行操作,那么原本的删除边的操作变为加入边的操作,用名次树维护每一个连通分量的名次,加边操作即是连通分量合并操作,每次将结点数小的子树向结点数大的子树合并,那么单次合并复杂度O(n1logn2),由于合并之后原本结点数少的子树结点数至少翻倍,所以每个结点最多被插入 logn 次,故总时间复杂度为 O(n log2n)  . 注意细节处理,代码如下: #include <cstdio> #include <cstdlib> #include <cstring>…
Treap实现名次树 前言 学平衡树的过程可以说是相当艰难.浏览Blog的过程中看到大量指针版平衡树,不擅长指针操作的我已经接近崩溃.于是,我想着一定要写一篇非指针实现的Treap的Blog. 具体如下. 简介 Treap(树堆,Tree+Heap)是一种强大的数据结构--每个节点除了本身键值(v)之外,附有一个随机优先级(p),其中v满足二叉搜索树性质,p满足堆性质(下文中为大根堆),通过旋转操作来维护性质,并使整棵树保持平衡. 名次树 顾名思义就是可以查找x的排名.查找第x名的值.查找前驱与…
                                                  Black Box 唉,一天几乎就只做了这道题,成就感颇低啊! 题意:有一系列插入查找操作,插入每次在有序数列中插入一个数,保证插入后数列还是有序,初始数列为空,每次查询一个排名为i的数,第i次查询排名为i的数.给你两个数列,第一个是插入数的顺序,第二个是每次查询发生在插入第U(i)个数之后.具体看样例,说实话我也理解了挺久,数列1 2 6 6 表示的是第一次查询是在插入第一个数之后,第二次查询是…
[la P5031&hdu P3726] Graph and Queries Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer v…
题意:给你个点m条边的无向图,每个节点都有一个整数权值.你的任务是执行一系列操作.操作分为3种... 思路:本题一点要逆向来做,正向每次如果删边,复杂度太高.逆向到一定顺序的时候添加一条边更容易.详见算法指南P235. #include<cstdlib> struct Node { Node *ch[]; // 左右子树 int r; // 随机优先级 int v; // 值 int s; // 结点总数 Node(int v):v(v) { ch[] = ch[] = NULL; r = r…
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20332 [思路] 时光倒流+名次树(rank tree). 所谓“时光倒流”即逆向处理,因为D删除边并不好操作所以我们倒着处理,删除边转化为添加边,C转化为将weight变回操作前的数,Q不变. 名次树实现以上操作:名次树是Treap+s域实现的,可以提供kth即查询第k大的数的操作和Treap的所有功能. 1)对于D(x):合并from[x]与to[x]所在的r…
题目来源:HDU 3726 Graph and Queries 题意:见白书 思路:刚学treap 參考白皮书 #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; struct Node { Node *ch[2]; int r; int v; int s; Node(int v): v(v) { ch[0] = ch[1] = NULL; r = rand(); s…
Treap名字的来源:Tree+Heap,正如名字一样,就是一颗简单的BST,一坨堆的合体.BST的不平衡的根本原因在于基于左<=根<=右的模式吃单调序列时候会无脑成长链,而Treap则添加一个优先级属性,值的大小随机生成,用最大堆的方式维护.之所以使用堆,是因为堆是一颗 完全二叉树,而BST梦寐以求的就是完全二叉结构,二者一结合,就产生了一种新的Balanced BST.Treap依赖于随机数,随机生成的优先级属性,通过简单的左右旋可以将长链旋转成近似完全二叉树结构,注意只是近似,平均情况下…
在主流STL版本中,set,map,都是BST实现的,具体来说是一种称为红黑树的动态平衡BST: 但是在竞赛中并不常用,因为红黑树过于复杂,他的插入 5 种,删除 6 中,代码量极大(如果你要改板子的话): 相比之下有一种Treap的动态平衡BST,却也可以做到插入,删除,查找的期望时间复杂度O(logn): 结点定义: struct Node { Node *ch[]; int r; //优先级 int v; //值 int s; //结点总数 Node(int v):v(v) { ch[]…