Poj--2761(划分树)

2014-09-30 20:52:36

思路:划分树裸体,不多说了,当练手吧。以后敲代码一定要聚精会神把算法思路重现,而不是默写!

 1 /*************************************************************************
 2     > File Name: 2761.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Tue 30 Sep 2014 08:00:27 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <queue>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 #define lpos (pos << 1)
18 #define rpos (pos << 1|1)
19 #define getmid(l,r) (l + (r - l) / 2)
20 typedef long long ll;
21 const int INF = 1 << 29;
22 const int maxn = 100010;
23 
24 int sorted[maxn];
25 
26 struct node{
27     int val[maxn];
28     int num[maxn];
29 }t[20];
30 
31 void Build_ptree(int pos,int l,int r){
32     if(l == r) return;
33     int mid = getmid(l,r);
34     int isame = mid - l + 1;
35     for(int i = l; i <= r; ++i)
36         if(t[pos].val[i] < sorted[mid]) --isame;
37     int ls = l,rs = mid + 1;
38     for(int i = l; i <= r; ++i){
39         t[pos].num[i] = (i == l ? 0 : t[pos].num[i - 1]);
40         if(t[pos].val[i] < sorted[mid]){
41             t[pos].num[i]++;
42             t[pos + 1].val[ls++] = t[pos].val[i];
43         }
44         else if(t[pos].val[i] > sorted[mid]){
45             t[pos + 1].val[rs++] = t[pos].val[i];
46         }
47         else{
48             if(isame){
49                 --isame;
50                 t[pos].num[i]++;
51                 t[pos + 1].val[ls++] = t[pos].val[i];
52             }
53             else t[pos + 1].val[rs++] = t[pos].val[i];
54         }
55     }
56     Build_ptree(pos + 1,l,mid);
57     Build_ptree(pos + 1,mid + 1,r);
58 }
59 
60 int Query_ptree(int a,int b,int k,int pos,int l,int r){
61     if(l == r) return t[pos].val[a];
62     int mid = getmid(l,r);
63     int preln,prern,ln,rn;
64     ln = t[pos].num[b] - (a == l ? 0 : t[pos].num[a - 1]);
65     preln = (a == l ? 0 : t[pos].num[a - 1]);
66     if(ln >= k){
67         a = l + preln;
68         b = l + preln + ln - 1;
69         return Query_ptree(a,b,k,pos + 1,l,mid);
70     }
71     else{
72         prern = a - l - preln;
73         rn = b - a + 1 - ln;
74         a = mid + 1 + prern;
75         b = mid + 1 + prern + rn - 1;
76         return Query_ptree(a,b,k - ln,pos + 1,mid + 1,r);
77     }
78 }
79 
80 int main(){
81     int n,m;
82     scanf("%d%d",&n,&m);
83     for(int i = 1; i <= n; ++i){
84         scanf("%d",&sorted[i]);
85         t[1].val[i] = sorted[i];
86     }
87     sort(sorted + 1,sorted + n + 1);
88     Build_ptree(1,1,n);
89     int a,b,c;
90     while(m--){
91         scanf("%d%d%d",&a,&b,&c);
92         printf("%d\n",Query_ptree(a,b,c,1,1,n));
93     }
94     return 0;
95 }
96     

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4002673.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值