码迷,mamicode.com
首页 > 其他好文 > 详细

[Luogu 1168] 中位数

时间:2017-12-20 14:54:39      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:https   string   amp   nod   lib   cst   blog   down   www.   

<题目链接>

中位数可以转化为区间第k大问题,因此想到Treap实现名次树。(笑)

插入第i个数,随即询问当前排名第(i+1>>1)的数。

代码走起。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
const int MAXN=100010;
int n;
class Treap
{
    public:
        Treap(void)
        {
            rt=cnt=0;
            memset(a,0,sizeof a);
            memset(s,0,sizeof s);
        }
        void Insert(int x)
        {
            _Insert(rt,x);
        }
        int Xth(int x)
        {
            return _Xth(rt,x);
        }
    private:
        bool a[MAXN];
        int rt,cnt,ans;
        struct node
        {
            int l,r,v,p,size,num;
        }s[MAXN];
        int Random(void)
        {
            int x;
            while(a[x=rand()%MAXN]);
            a[x]=1;
            return x;
        }
        void Update(int i)
        {
            s[i].size=s[s[i].l].size+s[s[i].r].size+s[i].num;
        }
        void L_Rotate(int &i)
        {
            int t=s[i].r;
            s[i].r=s[t].l,s[t].l=i;
            s[t].size=s[i].size;
            Update(i),i=t;
        }
        void R_Rotate(int &i)
        {
            int t=s[i].l;
            s[i].l=s[t].r,s[t].r=i;
            s[t].size=s[i].size;
            Update(i),i=t;
        }
        void _Insert(int &i,int x)
        {
            if(!i)
            {
                s[i=++cnt].v=x,s[i].p=Random();
                s[i].size=s[i].num=1;
                return;
            }
            ++s[i].size;
            if(x==s[i].v)
                ++s[i].num;
            else if(x<s[i].v)
            {
                _Insert(s[i].l,x);
                R_Rotate(i);
            }
            else
            {
                _Insert(s[i].r,x);
                L_Rotate(i);
            }
        }
        int _Xth(int i,int x)
        {
            if(!i)
                return 0;
            int t;
            if(x<=s[s[i].l].size)
                return _Xth(s[i].l,x);
            else if(x>(t=s[s[i].l].size+s[i].num))
                return _Xth(s[i].r,x-t);
            else
                return s[i].v;
        }
}T;
int main(int argc,char *argv[])
{
    scanf("%d",&n);
    srand((unsigned)time(NULL));
    for(int i=1,x;i<=n;++i)
    {
        scanf("%d",&x);
        T.Insert(x);
        if(i&1)
            printf("%d\n",T.Xth(i+1>>1));
    }
    return 0;
}

谢谢阅读。

[Luogu 1168] 中位数

标签:https   string   amp   nod   lib   cst   blog   down   www.   

原文地址:http://www.cnblogs.com/Capella/p/8072763.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!