博主sbit....对于高级数据结构深感无力,然后这些东西在OI竟然烂大街了,不搞就整个人都不好了呢. 于是我勇猛的跳进了这个大坑 ——sbit 区间K大的裸题,在线,无修改. 可以用归并树(\(O(nlog^3n)\)),也可用划分树(\(O(nlogn + mlogn)\)).果断划分树...(以后再来看归并树...再来看...来看..看..) 划分树是个什么东西呢?为什么可以做区间k大呢? 想想平衡树做k大时是如何搞的,其实内在原理是一样的. 划分树分两个步骤:建树与询问. 1. 建树 划…
关于主席树: 主席树(Chairman Tree)是一种离线数据结构,使用函数式线段树维护每一时刻离散之后的数字出现的次数,由于各历史版本的线段树结构一致,可以相减得出区间信息,即该区间内出现的数字和对应的数量,由于在线段树内,左子树代表的数字都小与右子树,便可像平衡树一样进行K大询问.新建一颗树是\(O(logn)\),查询一次也为\(O(logn)\). 比划分树好想&写多了,但是在POJ上比划分树慢一些. CODE: #include <cstdio> #include <…
链接 这树着实不好理解啊 讲解http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html 对于找K值 右区间的确定不是太理解..先当模板贴着吧 #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stdlib.h> using namespace std; #def…
题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用的方法有很多,我听过的只有主席树.整体二分法.划分树.分块…… 因为是看<挑战>书介绍的平方分割方法(分块),所以先把分块说了,其他的坑以后再填 分块算法思想是将区间分为若干块,一般分为 n1/2 块然后在每块维护所需信息,可以把复杂度降到 O(根号n) 具体的分析和代码在<挑战程序设计竞赛…
题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目大意:给定一个区间,以及一个k值,求该区间内小于等于k值的数的个数.注意区间是从0开始的. 解题思路: 首先这题线段树可以解.方法是维护一个区间最大值max,一个区间点个数s,如果k>max,则ans=s+Q(rson),否则ans=Q(lson). 然后也可以用求区间第K大的划分树来解决,在对原来求第K大的基础上改改就行,方法如下: Build方法同第K大. 对于Query: ①左区…
我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和前一颗树没有关系,so,并不需要可持久化,一个朴素的权值线段树就可以啦. 我们知道普通的线段树是刚开始就把所有的节点都开了,但我们发现并不需要,因为每个点里的操作并不是很多,很大一部分的节点是用不到的,那么我们就可以不开.用Ls 和 Rs 来记左右儿子的地址,随用随开即可. #include<bit…
Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序,并将所有排列编号(从0开始),给出排列的编号得到对应排列)用到的式子.可以想到用逆康托展开的方法.但是需要一些变化: ;i--) { s[i-]+=s[i]/(n-i+); s[i]%=(n-i+); } 例如:n=3时,3=0*2!+0*1!+3*0!应该变为3=1*2!+1*1!+0*0!.就…
K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 47066   Accepted: 15743 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing your previous task about key inse…
poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右子树(在子区间内数与数的相对位置保持不变),递归向下分割. 查询.toleft[p][i] 表示第 p 层前 i 个数中有多少个整数分入下一层.查询最重要的是确定新的查询区间,若递归查询左区间,则新的子区间的左边一定是上一层区间 [L, l - 1] 里的 toleft[dep][l-1] - to…
一棵树,不一定是二叉树,在每个结点最多只属于一条链的情况下,处理出其中最长的前k个的长度. 最近训练赛做到两道题了,有必要总结一下. 不过我不知道是否有更专门的叫法. 借鉴了这位大佬的博客:https://www.cnblogs.com/Aragaki/p/11754534.html 例题1. 2019-2020 ACM-ICPC Brazil Subregional Programming Contest D - Denouncing Mafia https://codeforces.com/…