HDU 2665 && POJ 2104(主席树)

http://poj.org/problem?id=2104

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <string>
 5 #include <cmath>
 6 #include <iostream>
 7 #include <stack>
 8 using namespace std;
 9 #define N 100010
10
11 /*
12 主席树
13 http://www.bilibili.com/video/av4619406/
14 http://www.cnblogs.com/Empress/p/4652449.html
15 题意:在一堆数里面有m个询问,每个询问求区间[l,r]里面的第k小的数是哪个.
16 要认识权值线段树:在以节点i为根的树中,[1,i]区间内包含的数的个数.
17 */
18 struct node
19 {
20     int l, r, sum;//sum储存的就是权值
21 }tree[N*40];
22 int root[N];//储存根节点
23 int a[N], b[N], tot;
24
25 void update(int pre, int &now, int x, int l, int r)
26 {
27     tree[++tot] = tree[pre];//把上一个版本的线段树给现在的版本,然后对要修改的那条链进行更新
28     now = tot;
29     tree[now].sum++;//因为插入了新的数,所以要更新+1
30     if(l == r) return ;
31     int m = (l + r) >> 1;
32     if(x <= m) update(tree[pre].l, tree[now].l, x, l, m);
33     else update(tree[pre].r, tree[now].r, x, m + 1, r);
34 }
35
36 int query(int left, int right, int k, int l, int r)
37 {
38     if(l == r) return l;
39     int m = (l + r) >> 1;
40     int sum = tree[tree[right].l].sum - tree[tree[left].l].sum;//如果左子树已经有k个数,那么答案就在左边
41     if(k <= sum) return query(tree[left].l, tree[right].l, k, l, m);
42     else return query(tree[left].r, tree[right].r, k - sum, m + 1, r);
43 }
44
45 int main()
46 {
47 //    int t;
48 //    scanf("%d", &t);
49 //    while(t--) {
50         int n, m;
51         scanf("%d%d", &n, &m);
52         tot = 0;
53         for(int i = 1; i <= n; i++) {
54             scanf("%d", &a[i]);
55             b[i] = a[i];
56         }
57         sort(b + 1, b + 1 + n);
58         int cnt = unique(b + 1, b + 1 + n) - b - 1;
59         for(int i = 1; i <= n; i++) {
60             a[i] = lower_bound(b + 1, b + 1 + cnt, a[i]) - b; //二分找到a[i]的位置
61 //            printf("QQQQQ\n");
62             update(root[i-1], root[i], a[i], 1, cnt); //root[i-1]表示上一个版本的线段树
63         }
64         for(int i = 1; i <= m; i++) {
65             int l, r, k;
66             scanf("%d%d%d", &l, &r, &k);
67             int ans = query(root[l-1], root[r], k, 1, cnt); //ans是第k个数的位置
68             printf("%d\n", b[ans]); //因为询问的是哪个数,所以要b[ans]
69         }
70 //    }
71     return 0;
72 }
时间: 2024-12-15 06:59:02

HDU 2665 && POJ 2104(主席树)的相关文章

[poj 2104]主席树+静态区间第k大

题目链接:http://poj.org/problem?id=2104 主席树入门题目,主席树其实就是可持久化权值线段树,rt[i]维护了前i个数中第i大(小)的数出现次数的信息,通过查询两棵树的差即可得到第k大(小)元素. #include<cstdio> #include<vector> #include<algorithm> using namespace std; #define lson(i) node[i].lson #define rson(i) node

[HDU 2665&amp;POJ 2104]K-th Number(主席树)

Description Give you a sequence and ask you the kth big number of a inteval. Solution 主席树模板题 敲完辣,心情瞬间变好,我要下楼看运动会 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #define MAXN 100005

poj 2104 主席树

附上题目链接: http://poj.org/problem?id=2104   很经典的一道主席树题, 题意是查询区间的第k大, http://blog.csdn.net/famousdt/article/details/7064866 这个博主讲的相当赞, 这里附上他的原话: 建树的过程比较简单,对于区间[l,r],首先通过对原数组的排序找到这个区间的中位数a[mid],小于a[mid]的数划入它的左子树[l,mid-1],大于它的划入右子树[mid,r].同时,对于第i个数a[i],记录在

poj 2104主席树求区间第k小

POJ - 2104 题意:求区间第k小 思路:无修改主席树 AC代码: #include "iostream" #include "iomanip" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set&

HDU 2665 Kth number 主席树裸题

题目链接 主席树详解 每次插入logn个点 这样就不需要重新建树了. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <fstream> #include <string> #include <time.h> #include <vector> #include <map> #include &

HDU 2665 Kth number (主席树)

题意:给定一个序列,求给定区间的第 k 小的值. 析:就是一个主席树的裸板. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring&g

Poj 2104(主席树入门

题目:静态查询区间第k大. 主席树入门题目,之前看的很多资料一上来就是动态区间第k大,看得很费劲,后来找了个写得清晰的,感觉静态的还不算难,代码也不长. /* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cs

hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)

http://acm.hdu.edu.cn/showproblem.php?pid=2665 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The first line is the number of the test cases. For each test case, the first line contain two integer n and m (

K-th Number POJ - 2104 划分树

K-th Number You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array