vijos P1081野生动物园 主席树求区间第K大

 

描述

cjBBteam拥有一个很大的野生动物园。这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子。这些狮子从北到南编号为1,2,3,…,N。每头狮子都有一个觅食能力值Ai,Ai越小觅食能力越强。饲养员cmdButtons决定对狮子进行M次投喂,每次投喂都选择一个区间[I,J],从中选取觅食能力值第K强的狮子进行投喂。值得注意的是,cmdButtons不愿意对某些区域进行过多的投喂,他认为这样有悖公平。因此cmdButtons的投喂区间是互不包含的。你的任务就是算出每次投喂后,食物被哪头狮子吃掉了。

格式

输入格式

输入第一行有两个数N和M。此后一行有N个数,从南到北描述狮子的觅食能力值。此后M行,每行描述一次投喂。第t+2的三个数I,J,K表示在第t次投喂中,cmdButtons选择了区间[I,J]内觅食能力值第K强的狮子进行投喂。

输出格式

输出有M行,每行一个整数。第i行的整数表示在第i次投喂中吃到食物的狮子的觅食能力值。

样例1

样例输入1[复制]

7 2
1 5 2 6 3 7 4
1 5 3
2 7 1

样例输出1[复制]

3
2

限制

各个测试点2s

提示

对于100%的数据,有1<=N<=100000,1<=M<=50000。

第一次“抄”主席树。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int M = 1000010;
 9 
10 struct Node{
11     int l, r, sum;
12 }T[M*20];
13 int T_cnt;
14 void inser(int &num, int &x, int L, int R) {
15      T[T_cnt++] = T[x]; x = T_cnt - 1;
16      ++T[x].sum;
17      if(L == R) return ;
18      int mid = (L + R) >> 1;
19      if(num <= mid) inser(num, T[x].l, L, mid);
20      else inser(num, T[x].r, mid + 1, R);
21  }
22 int query(int i, int j, int k, int L, int R) {
23      if(L == R) return L;
24      int t = T[T[j].l].sum - T[T[i].l].sum;
25      int mid = (R + L) >> 1;
26      if(k <= t) return query(T[i].l, T[j].l, k, L, mid);
27      else return query(T[i].r, T[j].r, k - t, mid + 1, R);
28  }
29 struct A{
30     int x, idx;
31     bool operator < (const A & o)const{
32         return x < o.x;
33     }
34 }a[M];
35 int ranks[M], root[M];
36 int n, m;
37 int main() {
38     T[0].l = T[0].r = T[0].sum = 0;
39     root[0] = 0;
40     while(~scanf("%d%d", &n, &m)){
41         for(int i = 1; i <= n; i++){
42             scanf("%d", &a[i].x);
43             a[i].idx = i;
44         }
45         sort(a+1, a+1+n);
46         for(int i = 1; i <= n; i++) ranks[a[i].idx] = i;
47         T_cnt = 1;
48         for(int i = 1; i <= n; i++){
49             root[i] = root[i-1];
50             inser(ranks[i], root[i], 1, n);
51         }
52        //printf("%SSS\n");
53         while(m--){
54             int i, j, k;
55             scanf("%d%d%d", &i, &j, &k);
56             printf("%d\n", a[query(root[i-1], root[j], k, 1, n)].x);
57         }
58     }
59     return 0;
60 }

 

posted on 2016-10-06 17:14  disppr  阅读(177)  评论(0编辑  收藏  举报