• Online Judge 2014 K-th Number -主席树


    You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. 
    That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?" 
    For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.InputThe first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000). 
    The second line contains n different integer numbers not exceeding 10 9 by their absolute values --- the array for which the answers should be given. 
    The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).OutputFor each question output the answer to it --- the k-th number in sorted a[i...j] segment.

    Sample Input

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

    Sample Output

    5
    6
    3

    Hint

    This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.


      很裸的主席树模板题。不知道可不可以用O(n1.5log2n)的莫队加平衡树来做。

      如果用下面这段代码去过poj的话会T掉,如果不是用new动态分配内存而是直接分配一个数组,在数组中储存所有节点可能就可以过了。

    Code

      1 /**
      2  * OpenJudge
      3  * Bailian#2104
      4  * Accepted
      5  * Time:2247ms
      6  * Memory:65536k
      7  */
      8 #include<iostream>
      9 #include<fstream>
     10 #include<sstream>
     11 #include<cstdio>
     12 #include<cstdlib>
     13 #include<cstring>
     14 #include<ctime>
     15 #include<cctype>
     16 #include<cmath>
     17 #include<algorithm>
     18 #include<stack>
     19 #include<queue>
     20 #include<set>
     21 #include<map>
     22 #include<vector>
     23 using namespace std;
     24 typedef bool boolean;
     25 #define smin(a, b)    (a) = min((a), (b))
     26 #define smax(a, b)    (a) = max((a), (b))
     27 template<typename T>
     28 inline void readInteger(T& u){
     29     char x;
     30     int aFlag = 1;
     31     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     32     if(x == -1){
     33         ungetc(x, stdin); 
     34         return;
     35     }
     36     if(x == '-'){
     37         x = getchar();
     38         aFlag = -1;
     39     }
     40     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
     41     ungetc(x, stdin);
     42     u *= aFlag;
     43 }
     44 
     45 typedef class SegTreeNode{
     46     public:
     47         int s;    //size
     48         SegTreeNode *left, *right;
     49         SegTreeNode():left(NULL), right(NULL), s(0){        }
     50         void pushUp(){
     51             this->s += this->left->s + this->right->s;
     52         }
     53 }SegTreeNode;
     54 
     55 typedef class SegTree{
     56     public:
     57         SegTreeNode* root;
     58         SegTree():root(NULL){        }
     59         SegTree(int size, int val){
     60             build(root, 1, size, val);
     61         }
     62         SegTree(SegTreeNode* root):root(root){    }
     63         
     64         void build(SegTreeNode*& node, int from, int end, int val){
     65             node = new SegTreeNode();
     66             if(from == end){
     67                 node->s = (val == from) ? (1) : (0);
     68                 return;
     69             }
     70             int mid = (from + end) >> 1;
     71             build(node->left, from, mid, val);
     72             build(node->right, mid + 1, end, val);
     73             node->pushUp();
     74         }
     75 }SegTree;
     76 
     77 typedef class Pair{
     78     public:
     79         int data;
     80         int index;
     81         Pair(const int data = 0, const int index = 0):data(data), index(index){        }
     82         boolean operator < (Pair another) const {
     83             return data < another.data;
     84         }
     85 }Pair;
     86 
     87 typedef class ChairTree{    //主席树
     88     public: 
     89         SegTree* st;
     90         int* discrete;
     91         map<int, int> to;
     92         int len;
     93         ChairTree():st(NULL), discrete(NULL){        }
     94         ChairTree(int* lis, int len):len(len){
     95             discrete = new int[(const int)(len + 1)];
     96             memcpy(discrete, lis, sizeof(int) * (len + 1));
     97             sort(discrete + 1, discrete + len + 1);
     98             for(int i = 1; i <= len; i++)
     99                 to[discrete[i]] = i;
    100             st = new SegTree[(const int)(len + 1)];
    101             st[0] = SegTree(len, 0);
    102             for(int i = 1; i <= len; i++){
    103                 st[i] = SegTree();
    104                 appendSegTree(st[i].root, st[i - 1].root, 1, len, to[lis[i]]);
    105             }
    106         }
    107         
    108         void appendSegTree(SegTreeNode*& node, SegTreeNode*& before, int from, int end, int val){
    109             node = new SegTreeNode();
    110             if(from == end){
    111                 node->s = 1;
    112                 return;
    113             }
    114             int mid = (from + end) >> 1;
    115             if(val <= mid){
    116                 node->right = before->right;
    117                 appendSegTree(node->left, before->left, from, mid, val);
    118             }else{
    119                 node->left = before->left;
    120                 appendSegTree(node->right, before->right, mid + 1, end, val);
    121             }
    122             node->pushUp();
    123         }
    124         
    125         int query(int l, int r, SegTreeNode*& left, SegTreeNode*& right, int k){
    126             if(l == r){
    127                 return l;
    128             }
    129             int ls = left->left->s - right->left->s;
    130             int mid = (l + r) >> 1;
    131             if(ls >= k)    return query(l, mid, left->left, right->left, k);
    132             return query(mid + 1, r, left->right, right->right, k - ls);
    133         }
    134         
    135         int query(int from, int end, int k){
    136             return discrete[query(1, len, st[end].root, st[from - 1].root, k)];
    137         }
    138 }ChairTree;
    139 
    140 int n, m;
    141 ChairTree ct;
    142 int *lis;
    143 
    144 inline void init(){
    145     readInteger(n);
    146     readInteger(m);
    147     lis = new int[(const int)(n + 1)];
    148     for(int i = 1; i <= n; i++){
    149         readInteger(lis[i]);
    150     }
    151     ct = ChairTree(lis, n);
    152 }
    153 
    154 inline void solve(){
    155     int l, r, k;
    156     while(m--){
    157         readInteger(l);
    158         readInteger(r);
    159         readInteger(k);
    160         int res = ct.query(l, r, k);
    161         printf("%d
    ", res);
    162     }
    163 }
    164 
    165 int main(){
    166     init();
    167     solve();
    168     return 0;
    169 }    
  • 相关阅读:
    一起学ORBSLAM(2)ORB特征点提取
    SIFT特征浅析
    数字图像处理之均值滤波,高斯滤波,中值滤波,双边滤波
    STM32的GPIO
    静态锁问题
    一起学ORBSLAM2(3)system框架搭建
    构造函数/拷贝构造函数/赋值运算符/移动构造函数/移动赋值运算符几个的区别与相似之处
    一起学ROS之日志消息,命名规范,消息录制与回放
    C语言 ---- 函数 结构体 iOS学习-----细碎知识点总结
    C语言 ---- 数组 iOS学习-----细碎知识点总结
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6347884.html
Copyright © 2020-2023  润新知