可持久化数据结构题目泛做。

个人理解:

每个新的线段树的一个结点保存的是1...位置 i中的数字在相应的区间上有几个。

然后我们用r-(l-1)得到的就是l...r上的中字在相应的区间中出现了几个。

题目1 POJ2104

题目大意:静态查询区间第K小值。

裸的可持久化线段树。

 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6
 7 using namespace std;
 8 const int N = 100000 + 5;
 9
10 struct SegTree {
11   int l, r, size;
12 }Node[N * 30];
13
14 struct data {
15   int v, pos;
16   bool operator < (const data &k) const {
17     return v < k.v;
18   }
19 }a[N];
20
21 int n, m, rank[N], l, r, k, root[N], tot;
22
23 void build(int &o, int l, int r) {
24   o = ++ tot;
25   Node[o].l = Node[o].r = Node[o].size = 0;
26   if(l >= r) return;
27   int mid = (l + r) >> 1;
28   build(Node[o].l, l, mid);
29   build(Node[o].r, mid + 1, r);
30 }
31
32 void update(int pre, int &o, int l, int r, int kth) {
33   o = ++ tot;
34   Node[o] = Node[pre];
35   Node[o].size ++;
36   if(l >= r) return;
37   int mid = (l + r) >> 1;
38   if(kth <= mid)
39     update(Node[pre].l, Node[o].l, l, mid, kth);
40   else
41     update(Node[pre].r, Node[o].r, mid + 1, r, kth);
42 }
43
44 int query(int r1, int r2, int l, int r, int kth) {
45   if(l >= r) return l;
46   int lc = Node[Node[r2].l].size - Node[Node[r1].l].size;
47   int mid = (l + r) >> 1;
48   if(lc >= kth)
49     return query(Node[r1].l, Node[r2].l, l, mid, kth);
50   else
51     return query(Node[r1].r, Node[r2].r, mid + 1, r, kth - lc);
52 }
53
54 int main() {
55   scanf("%d%d", &n, &m);
56   for(int i = 1; i <= n; ++ i) {
57     scanf("%d", &a[i].v);
58     a[i].pos = i;
59   }
60   sort(a + 1, a + n + 1);
61   for(int i = 1; i <= n; ++ i)
62     rank[a[i].pos] = i;
63   build(root[0], 1, n);
64   for(int i = 1; i <= n; ++ i)
65     update(root[i - 1], root[i], 1, n, rank[i]);
66   for(int i = 1; i <= m; ++ i) {
67     scanf("%d%d%d", &l, &r, &k);
68     printf("%d\n", a[query(root[l - 1], root[r], 1, n, k)].v);
69   }
70   return 0;
71 }

2104

时间: 2024-10-09 01:29:35

可持久化数据结构题目泛做。的相关文章

[DynamicProgramming]动态规划题目泛做

Educational Codeforces Round 12 F 大意: 求n(n<=1011)以内恰好有4个因数的数的个数 分析: 首先一个数恰好有4个因数,说明它质因数分解之后是两个质数的乘积或是一个质数的三次方,对于后一种情况我们直接n1/3就能算出来,关键在于计算n以内有多少个数是两个素数的乘积. 设n=p1?p2,则必然有p1<n?√,p2>n?√,我们枚举p1,那么问题就在于np1 内有多少个素数. 这一点我们用dp来解决. 记pj为第j个素数,dp[n][j]为[1,n]

小题目泛做

题目1 CodeForces 605 A 题目大意:给定一个长度为n的序列,每次可以把一个数放到开头或者最后,求升序排好的最小次数. 求出原序列位置的最长上升子序列,用n减去最大的.我们只要保证相对大小不变就可以了. Code: 1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdlib> 5 #include <cstring> 6 7

最大权闭合子图题目泛做

题目1 POJ2987 题目大意: 一个公司要裁员,每个成员都有自己的效益值,可正可负,而且每个人都有自己的直接下属,如果某个人被裁员,那么他的直接下属,他的下属的下属....都会离开这家公司. 现在请你确定裁员的方案,求最小裁员人数和公司的最大收益. 算法讨论: 选了一个点,其后继都必须要选,这是闭合子图的特点.所以这个题就是裸题啦. 最小裁员人数就是与S相连的点数,公司的最大收益就是正权和-最小割. Code: 1 #include <cstdlib> 2 #include <cst

网络流题目泛做(费用流的不写在这里面)

题目1 ZJOI 最小割 题目大意: 求一个无向带权图两点间的最小割,询问小于等于c的点对有多少. 算法讨论: 最小割 分治 代码: #include <cstdlib> #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <vector> using namespace std; const int N = 15

二分图题目泛做(为了对应陈学姐的课件)

题1:BZOJ1854 SCOI2010游戏 每个属性x,y分别向i连条边,匹配到不能匹配为止. 输出即可. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int N = 1000000 + 5; 10 11 i

noi往届题目泛做

noi2015 Day1 t1 程序自动分析  离散化+并查集 t2 软件包管理器  裸树链剖分 t3 寿司晚宴  状压dp Day2 t1 荷马史诗 哈夫曼多叉树 t2 品酒大会 后缀数组按照height排序+并查集 t3 小园丁与老司机 noi2014 Day1 t1 起床困难综合症  按位dp,贪心 t2 魔法森林 link-cut-tree维护MST t3 题答 Day2 t1 动物园 KMP简单题 t2 随机数生成器  贪心,每一行的区间是连续不跨越的,卡内存 t3 购票 树链剖分+线

可持久化数据结构

可持久化数据结构 题目链接:http://acm.xidian.edu.cn/problem.php?id=1181 用vector实现可持久化 这题要求的是一个支持区间查询的可持久化数据结构.这里使用vector巧妙地实现:pair<time,value>用pair存储时间戳以及当前时间的值,query的时候使用二分查找即可. 代码如下: 1 #include<cstdio> 2 #include<vector> 3 #include<iostream>

历年NOIP水题泛做

快noip了就乱做一下历年的noip题目咯.. noip2014 飞扬的小鸟 其实这道题并不是很难,但是就有点难搞 听说男神错了一个小时.. 就是$f_{i,j}$表示在第$i$个位置高度为$j$的时候最小点击次数 递推的话对于上升的情况只做一次,后面几次在后面再做.. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace st

# 清北冬令营真题泛做

清北冬令营真题泛做 前言 这段时间为了准备冬令营把清北冬令营真题都做了一下.更个博回顾一下(免得你们老说我咕咕咕). 先写良心PKU的题再写THU的题, 主要是THU的题和PKU比起来真的毒瘤好多...... PKUWC2018 [PKUWC2018]Minimax 一个比较显然的暴力是归并排序,每次直接前后缀计算答案即可. 为啥不用线段树合并代替归并排序呢? 暴力线段树合并,合并的过程中顺便算一下即可,由于权值区间不交所以复杂度一个\(log\). [PKUWC2018]Slay the Sp