poj 2104 划分树模板

划分树的模板题。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 using namespace std;
 5
 6 const int N = 100001;
 7 int tree[20][N];
 8 int sum[20][N];
 9 int as[N];
10
11 void build( int p, int l, int r )
12 {
13     int mid = ( ( l + r ) >> 1 );
14     int lm = 0, ls = l, rs = mid + 1;
15     for ( int i = mid; i >= l; i-- )
16     {
17         if ( as[i] == as[mid] )
18             lm++;
19         else
20             break;
21     }
22     for ( int i = l; i <= r; i++ )
23     {
24         if ( i == l )
25             sum[p][i] = 0;
26         else
27             sum[p][i] = sum[p][i - 1];
28         if ( tree[p][i] == as[mid] )
29         {
30             if ( lm )
31             {
32                 lm--;
33                 sum[p][i]++;
34                 tree[p + 1][ls++] = tree[p][i];
35             }
36             else
37             {
38                 tree[p + 1][rs++] = tree[p][i];
39             }
40         }
41         else if ( tree[p][i] < as[mid] )
42         {
43             sum[p][i]++;
44             tree[p + 1][ls++] = tree[p][i];
45         }
46         else
47         {
48             tree[p + 1][rs++] = tree[p][i];
49         }
50     }
51     if ( l == r )
52         return ;
53     build( p + 1, l, mid );
54     build( p + 1, mid + 1, r );
55 }
56
57 int query( int p, int l, int r, int ql, int qr, int k )
58 {
59     if ( l == r )
60         return tree[p][l];
61     int mid = ( ( l + r ) >> 1 );
62     int s, ss;
63     if ( ql == l )
64         s = 0, ss = sum[p][qr];
65     else
66         s = sum[p][ql - 1], ss = sum[p][qr] - s;
67     if ( k <= ss )
68         return query( p + 1, l, mid, l + s, l + sum[p][qr] - 1, k );
69     else
70         return query( p + 1, mid + 1, r, mid + 1 - l + ql - s, mid + 1 - l + qr - sum[p][qr], k - ss );
71 }
72
73 int main ()
74 {
75     int n, m;
76     while ( scanf("%d%d", &n, &m) != EOF )
77     {
78         for ( int i = 1; i <= n; i++ )
79         {
80             scanf("%d", as + i);
81             tree[0][i] = as[i];
82         }
83         sort( as + 1, as + 1 + n );
84         build( 0, 1, n );
85         while ( m-- )
86         {
87             int a, b, c;
88             scanf("%d%d%d", &a, &b, &c);
89             printf("%d\n", query( 0, 1, n, a, b, c ));
90         }
91     }
92     return 0;
93 }
时间: 2024-10-12 08:06:14

poj 2104 划分树模板的相关文章

POJ 2104 划分树模板题

给出n,m n个数字 m次询问,每次询问(l,r)区间的第k小的数 划分树模板 mark一下 #include "stdio.h" #include "string.h" #include "algorithm" using namespace std; int a[100010],as[100010]; int tree[20][100010];// 记录第i层元素序列 int sum[20][100010];// 记录第i层的1~j划分到左子

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

poj 2104 K-th Number(划分树模板)

划分树模板题,敲上模板就ok了. #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define MP

poj 2401 划分树 求区间第k大的数

题目:http://poj.org/problem?id=2104 划分树待我好好理解下再写个教程吧,觉得网上的内容一般,,, 模板题: 贴代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define CLR(a) memset(a,0,sizeof(a)) const int MAXN = 1000

POJ--2104--K-th Number【划分树模板】

链接:http://poj.org/problem?id=2104 题意:给一个n个元素的数组,m次询问,每次查询区间[i,j]中第k大的数,输出这个数. 思路:划分树模板题 划分树讲解:传送门 我用的是kuangbin大神的模板 #include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio&

划分树模板题

原题http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 37130   Accepted: 11974 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing

划分树模板

1 ///划分树模板,找区间第k小的数 2 const int mx=1e5+5; 3 int tree[30][mx]; 4 int sortt[mx]; 5 int sum[30][mx]; 6 7 void build(int l,int r,int c) 8 { 9 if (l==r) return ; 10 int m=(l+r)>>1; 11 int isame=m-l+1; 12 int pl=l,pr=m+1; 13 for (int i=l;i<m;i++) 14 if

划分树 模板

#include <iostream> #include <cstdio> #include <algorithm> using namespace std; #define N 100500 #define MID ((l+r)>>1) int a[N],s[N],t[20][N],num[20][N],n,m; // void build(int lft,int rht,int ind) // { // if(lft==rht) return; // /

poj 2104主席树求区间第k小

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