hdu 2665 Kth number

题意:无修改的区间第k小问题。

p.s.终于能用三种方法搞定这道题了,开心~

  划分树的方法喜闻乐见;

  线段树套平衡树然后二分枚举答案,写起来比较麻烦;

  今天刚刚想明白函数式线段树>_<,发现写这个还挺方便;

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N = (int)3e6+10;
 6 const int maxn = (int)1e5;
 7 int lson[N],rson[N],sum[N];
 8 int Time[N];
 9 int total;
10 int s[N],X[N];
11 void pushup(int root){
12     sum[root] = sum[lson[root]] + sum[rson[root]];
13 }
14 int build(int L,int R){
15     int now = ++total;
16     if(L==R){
17         lson[now] = rson[now] = 0;
18         sum[now] = 0;
19         return now;
20     }
21     int m=(L+R)>>1;
22     lson[now] = build(L,m);
23     rson[now] = build(m+1,R);
24     pushup(now);
25     return now;
26 }
27 int update(int root,int pos,int L,int R){
28     int now = ++total;
29     if(L==R){
30         sum[now] = sum[root] + 1;
31         lson[now] = rson[now] = 0;
32         return now;
33     }
34     int m=(L+R)>>1;
35     if(pos<=m){
36         lson[now] = update(lson[root],pos,L,m);
37         rson[now] = rson[root];
38     }else{
39         lson[now] = lson[root];
40         rson[now] = update(rson[root],pos,m+1,R);
41     }
42     pushup(now);
43     return now;
44 }
45 int ask(int root1,int root2,int k,int L,int R){
46     if(L==R){
47         return X[L];
48     }
49     int number = sum[lson[root2]] - sum[lson[root1]];
50     int m=(L+R)>>1;
51     if(number >= k)
52         return ask(lson[root1],lson[root2],k,L,m);
53     else
54         return ask(rson[root1],rson[root2],k-number,m+1,R);
55 }
56 int main(){
57     int T;scanf("%d",&T);
58     int n,m;
59     while(T--){
60         scanf("%d%d",&n,&m);
61         int cnt = 0;
62         for(int i=1;i<=n;i++){
63             scanf("%d",&s[i]);
64             X[++cnt] = s[i];
65         }
66         sort(X+1,X+1+cnt);
67         int all = 1;
68         for(int i=2;i<=cnt;i++)
69             if(X[i]!=X[i-1])X[++all] = X[i];
70         total = 0;
71         Time[0] = build(1,all);
72         for(int i=1;i<=n;i++){
73             int pos = lower_bound(X+1,X+1+all,s[i])-X;
74             Time[i] = update(Time[i-1],pos,1,all);
75         }
76         while(m--){
77             int L,R,k;
78             scanf("%d%d%d",&L,&R,&k);
79             printf("%d\n",ask(Time[L-1],Time[R],k,1,all));
80         }
81     }
82     return 0;
83 }

 

  

 

posted @ 2013-06-03 14:36  silver__bullet  阅读(214)  评论(0编辑  收藏  举报