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

[Luogu 2073] 送花

时间:2017-12-21 19:36:13      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:val   cti   time   include   代码   private   div   org   clu   

<题目链接>

很容易想到的平衡树,加个维护区间和。

只需要插入和删除操作即可。

kth其实都不用的,最小和最大可以从根节点log n一直向左/一直向右跑到叶子节点而求得。

记得每插入完一个点一定要更新区间和!!更新区间和!!更新区间和!!

我就因为没更新,导致出来答案都是随机的,有时候对,有时候不对。

关于平衡树不多说啦,关于平衡树(Treap)的教程请看这里

上代码。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
const int MAXN=100010;
int n,w,x;
class Treap
{
    public:
        Treap(void)
        {
            rt=cnt=0;
            memset(a,0,sizeof a);
            memset(s,0,sizeof s);
        }
        void Insert(int w,int x)
        {
            _Insert(rt,w,x);
        }
        void Delete(bool l)
        {
            int i=Find(rt,l);
            _Delete(rt,s[i].w,s[i].v);
        }
        void Answer(void)
        {
            printf("%d %d",s[rt].bty,s[rt].val);
        }
    private:
        bool a[MAXN];
        int rt,cnt;
        struct node
        {
            int l,r,w,v,p,bty,val;
        }s[MAXN];
        int Random(void)
        {
            int x;
            while(a[x=rand()%MAXN]);
            a[x]=1;
            return x;
        }
        void Update(int i)
        {
            s[i].bty=s[s[i].l].bty+s[s[i].r].bty+s[i].w;
            s[i].val=s[s[i].l].val+s[s[i].r].val+s[i].v;
        }
        void L_Rotate(int &i)
        {
            int t=s[i].r;
            s[i].r=s[t].l,s[t].l=i;
            Update(i),Update(t),i=t;
        }
        void R_Rotate(int &i)
        {
            int t=s[i].l;
            s[i].l=s[t].r,s[t].r=i;
            Update(i),Update(t),i=t;
        }
        void _Insert(int &i,int w,int x)
        {
            if(!i)
            {
                s[i=++cnt].bty=s[i].w=w,s[i].val=s[i].v=x;
                s[i].p=Random();
                return;
            }
            if(x==s[i].v)
                return;
            if(x<s[i].v)
            {
                _Insert(s[i].l,w,x);
                if(s[s[i].l].p>s[i].p)
                    R_Rotate(i);
            }
            else
            {
                _Insert(s[i].r,w,x);
                if(s[s[i].r].p>s[i].p)
                    L_Rotate(i);
            }
            Update(i);//一定要更新!!
        }
        void _Delete(int &i,int w,int x)
        {
            if(!i)
                return;
            if(x==s[i].v)
            {
                if(!s[i].l || !s[i].r)
                    i=s[i].l | s[i].r;
                else if(s[s[i].l].p>s[s[i].r].p)
                    R_Rotate(i),_Delete(i,w,x);
                else
                    L_Rotate(i),_Delete(i,w,x);
                return;
            }
            s[i].bty-=w,s[i].val-=x;
            if(x<s[i].v)
                _Delete(s[i].l,w,x);
            else
                _Delete(s[i].r,w,x);
        }
        int Find(int i,bool l)
        {
            if(l)
                while(s[i].l)
                    i=s[i].l;
            else
                while(s[i].r)
                    i=s[i].r;
            return i;
        }
}T;
int main(int argc,char *argv[])
{
    srand((unsigned)time(NULL));
    while(~scanf("%d",&n) && ~n)
        switch(n)
        {
            case 1:
                scanf("%d %d",&w,&x);
                T.Insert(w,x);
                break;
            case 2:
                T.Delete(0);
                break;
            case 3:
                T.Delete(1);
                break;
        }
    T.Answer();
    return 0;
}

谢谢阅读

[Luogu 2073] 送花

标签:val   cti   time   include   代码   private   div   org   clu   

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

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