码迷,mamicode.com
首页 > 其他好文 > 详细

划分树

时间:2015-11-18 14:02:00      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 const int MAXN = 100010;
 8 int tree[30][MAXN];   //each row has numbers
 9 int sorted[MAXN];
10 int toleft[30][MAXN];  // 表示第i层从1到i有多少个数分入到左边
11 
12 void buid(int l,int r,int dep)
13 {
14     if ( l== r) return ;         
15     int mid = (l+r)>>1;
16     int same = mid-l+1; //中间值而且被分入左边的个数
17     for (int i = l;i<=r;i++)
18         if (tree[dep][i] < sorted[mid])
19             same--;
20     int lpos = l;
21     int rpos = mid+1;
22     for (int i = l;i<=r;i++)
23     {
24         if (tree[dep][i] < sorted[mid])
25             tree[dep+1[lpos++] = tree[dep][i];
26         else if (tree[dep][i] == sorted[mid] && same > 0)
27         {
28             tree[dep+1][lpos++] = tree[dep][i];
29             same--;
30         }
31         else
32             tree[dep+1][rpos++] = tree[dep][i];
33         toleft[dep][i] = toleft[dep][l-1]+lpos-1;//从1到i放到左边的个数
34     }
35     build(l,mid,dep+1);
36     build(mid+1,r,dep+1);
37 }
38 
39 int query(int l,int R,int l,int r,int dep,int k) //第K大   传L,R利用L,R进行区间的缩小
40 {
41     if (l == r) return tree[dep][l];
42     int mid = (L+R) >> 1;
43     int cnt = toleft[dep][r] - toleft[dep][l-1];  // 【l,r】中位于左边的个数   二分的意
44     if(cnt >=k)
45     {
46         // L+要查询的区间被放到左边的个数
47         int newl = L + toleft[dep][l-1] - toleft[dep][L-1];
48         int newr = newl + cnt -1;
49         return query(L,mid,newl,newr,dep+1,k);
50     }
51     else
52     {
53         int newr = r + toleft[dep][R] - toleft[dep][r];
54         int newl = newr - (r-l-cnt);
55         return query(mid+1,R,newl,newr,dep+1,k-cnt);
56     }
57 }
58 
59 
60 int main()
61 {
62     int T;
63     int n,m;
64     int s,t,k;
65     scanf("%d",&T);
66     while (T--)
67     {
68         scanf("%d%d",&n,&m);
69         memset(tree,0,sizeof(tree));
70         for (int i = 1;i<=n;i++)
71         {
72             scanf("%d",&tree[0][i]);  // 将数字放到第一层 然后利用划分 其实是归并 进行建树
73             sorted[i] = tree[0][i];
74         }
75         sort(sorted+1;sorted+n+1);    // sort tree
76         build(1,n,0);
77         while (m--)
78         {
79             scanf("%d%d%d",&s,&t,&k);
80             printf("%d\n",query(1,n,s,t,0,k));
81         }
82     }
83     return 0;
84 }
划分树

不保证代码能编译过

上课写的 忘带u盘了

划分树

标签:

原文地址:http://www.cnblogs.com/yifi/p/4974070.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!