zoukankan      html  css  js  c++  java
  • 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
    ");
    53         while(m--){
    54             int i, j, k;
    55             scanf("%d%d%d", &i, &j, &k);
    56             printf("%d
    ", a[query(root[i-1], root[j], k, 1, n)].x);
    57         }
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    ubuntu 安装 redis desktop manager
    ubuntu 升级内核
    Ubuntu 内核升级,导致无法正常启动
    spring mvc 上传文件,但是接收到文件后发现文件变大,且文件打不开(multipartfile)
    angular5 open modal
    POJ 1426 Find the Multiple(二维DP)
    POJ 3093 Margritas
    POJ 3260 The Fewest Coins
    POJ 1837 Balance(二维DP)
    POJ 1337 A Lazy Worker
  • 原文地址:https://www.cnblogs.com/cshg/p/5934138.html
Copyright © 2011-2022 走看看