• 题解:中位数


    传送门

    首先考虑的是二叉搜索树,每次查找当前排名(i+1)/2的数。但是对于某些数据,其递归层数过多,会导致爆栈。

    那么显然可以用Treap或Splay。

    这里考虑线段树:

    由于线段树是一种平衡树,所以一定保证能跑出来。

    对于线段树,我们基于二叉搜索树的查找方法并介于线段树平衡的性质求解。

    对于线段树的每一个节点,我们记其大小为num,并记录其左边最大值和右边最小值。

    在插入时我们考虑存入一个有序数列,保证其根节点的元素单调递增。

    则其左边最大值和右边最小值分别为左儿子右端点和右儿子左端点。

    在插入时,若:

       当前值x=左最大=右最小,显然x=根节点。

    我们令根节点的num+1.

       当前值x>左最大,往右放;反之,往左放。

    在查询时:

      就相当于结合了二叉搜索树的找排名,和线段树的单点修改的样子。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define lson l,mid,rn<<1
    #define rson mid+1,r,rn<<1|1
    using namespace std;
    int n,a[100010],b[100010],size;
    struct cym{
        int num;
        int l_size,r_size;
    }tree[400010];
    void update(int rn)
    {
        tree[rn].num=tree[rn<<1].num+tree[rn<<1|1].num;
        tree[rn].l_size=tree[rn<<1].l_size;tree[rn].r_size=tree[rn<<1|1].r_size;
    }
    void build(int l,int r,int rn)
    {
        if(l==r)
        {
            tree[rn].l_size=tree[rn].r_size=b[l];
            return;
        }
        int mid=(l+r)>>1;
        build(lson);
        build(rson);
        update(rn);
    }
    void add(int x,int now)
    {
        if(tree[now].l_size==tree[now].r_size&&tree[now].l_size==x)
        {
            tree[now].num++;
            return;
        }
        if(x>tree[now<<1].r_size)
        add(x,now<<1|1);
        else
        add(x,now<<1);
        update(now);
    }
    int find(int l,int r,int rn,int rank)
    {
        if(l==r)
        return tree[rn].l_size;
        int mid=(l+r)>>1;
        int ans=0;
        if(rank<=tree[rn<<1].num)
        ans=find(lson,rank);
        else
        ans=find(rson,rank-tree[rn<<1].num);
        return ans;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        size=unique(b+1,b+1+n)-(b+1);
        build(1,size,1);
        for(int i=1;i<=n;i++)
        {
            add(a[i],1);
            if(i&1)
            printf("%d
    ",find(1,size,1,(i+1)>>1));
        }
    }
  • 相关阅读:
    POI使用介绍
    Git的使用简介
    SOA架构搭建---duboo+zookeeper+SSM实现
    分布式事务介绍
    兼容安卓微信调用摄像头
    cookie
    js对手机软键盘的监听
    input 改变placeholder默认样式
    VisualVm使用JMX的方式连接远程JVM
    update批量根据条件更新
  • 原文地址:https://www.cnblogs.com/zzh666/p/9181274.html
Copyright © 2020-2023  润新知