zoukankan      html  css  js  c++  java
  • 洛谷

    这道题是提高+省选-的难度,做出来的话对数据结构题目的理解会增加很多。

    可以使用一种叫做对顶堆的东西,对顶堆是在线维护第n小的logn的算法。大概的思路是,假如我们要找的是第n小,我们就维护一个大小为n的(位于下方的)大顶堆,(位于上方的)小顶堆中每个元素都比大顶堆的大。在这道题中,n不变时每次有新的比他小的就把堆顶弹出到对顶(也就是小顶堆)的堆顶,每次n扩大的时候就从(上面的)小顶堆里取出堆顶放进大顶堆的堆顶……

    但是看样子应该其他平衡树也是可以解决这个问题的。比如支持快速名次的splay?还有完全另一个维度复杂的主席树(区间第k大)。

    这道题应该是对顶堆最简单了。但是明显是用别的数据结构更好,因为对顶堆的第n小只能慢慢变……这样真的不如splay……(当然啦!splay这么复杂,你怎么不用主席树呢?主席树还区间第k大呢?)

    Pdalao说了一个,可以用BST来维护,每个节点维护左子树的名次,那么找k的时候就可以判断是进入左子树还是右子树了,陷入思考……其实还是要旋转来保持平衡树的特性……

    真实的递归学习法,一个两个都不会。


    动态维护第k小也可以交给各类平衡树去完成。 而且k还可以不断改。

    对顶堆用来维护一种顶堆只会不断扩大的情形非常方便。和之前的动态求中位数一个道理。

    这里我们根据题目命名为“黑匣子堆”:注意每次顶堆扩大时,假如底堆有元素则优先从底堆获取。

    #include<bits/stdc++.h>
    using namespace std;
    
    struct Black_Box_Heap{
        //top_heap has the min element,bottom heap has the max element
    
        priority_queue<int,vector<int>,less<int> > top_heap;
        priority_queue<int,vector<int>,greater<int> > bottom_heap;
    
        int i;
    
        Black_Box_Heap(){i=0;}
    
        void add(int value){
            if(top_heap.size()<=i){
                top_heap.push(value);
            }
            else{
                if(value<top_heap.top()){
                    bottom_heap.push(top_heap.top());
                    top_heap.pop();
                    top_heap.push(value);
                }
                else{
                    bottom_heap.push(value);
                }
            }
        }
    
        int get(){
            int t=top_heap.top();
            i++;
            while(top_heap.size()<=i&&!bottom_heap.empty()){
                top_heap.push(bottom_heap.top());
                bottom_heap.pop();
            }
            return t;
        }
    }bbh;
    
    int a[200005];
    
    int main(){
        int m,n;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=m;i++){
            scanf("%d",&a[i]);
        }
    
        int j=1;
        for(int i=1;i<=n;i++){
            int u;
            scanf("%d",&u);
            while(u>=j){
                bbh.add(a[j]);
                j++;
            }
    
            printf("%d
    ",bbh.get());
        }
    }
  • 相关阅读:
    近期学习情况
    java连接数据库的两种方法总结
    近两个星期学习成果
    云笔记第一阶段总结
    圆面积
    C++计算器项目的初始部分
    C++视频课程
    A+B Format
    大一下学期的自我目标
    Kohana的请求流
  • 原文地址:https://www.cnblogs.com/Yinku/p/10319627.html
Copyright © 2011-2022 走看看