zoukankan      html  css  js  c++  java
  • 【题解】Luogu P2073 送花

    原题传送门

    这题需要用到Splay

    我们用一棵splay维护金钱

    考虑c<=1000000

    我们珂以把每种价格现在对应的美丽值存在一个a数组中

    这样讲有珂能不太清楚qaq,还是对着操作一个一个讲

    操作一:

    先在这棵splay中查找是否有这种花的金钱

    如果有,直接跳过

    如果没有,a[c]=m,把金钱为c的花的美丽值存下,把两个所求答案更新,把c插入平衡树

    操作2,3:

    执行所有操作之前先把inf,-inf插入平衡树

    删除最小就是删除-inf的后继,删除最大就是删除inf的前驱

    但还要加上特判,在后继(前驱)不等于inf(-inf)的情况下,更新答案,a数组变成0,把该节点从平衡树中删除

    完整代码

    #include <bits/stdc++.h>
    #define inf 1000000005
    #define N 100005
    #define root tree[0].ch[1]
    using namespace std;
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf; 
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    }
    inline int read()
    {
        register int x=0,f=1;register char ch=nc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=nc();
        return x*f;
    }
    inline void write(register int x)
    {
        if(!x)putchar('0');if(x<0)x=-x,putchar('-');
        static int sta[20];register int tot=0;
        while(x)sta[tot++]=x%10,x/=10;
        while(tot)putchar(sta[--tot]+48);
    }
    struct Splay{
        int v,fa,ch[2],sum;
    }tree[N];
    int tot;
    inline bool findd(register int x)
    {
        return x==tree[tree[x].fa].ch[0]?0:1;
    }
    inline void connect(register int x,register int fa,register int son)
    {
        tree[x].fa=fa;
        tree[fa].ch[son]=x;
    }
    inline void update(register int x)
    {
        tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+1;
    }
    inline void rotate(register int x)
    {
        int Y=tree[x].fa;
        int R=tree[Y].fa;
        int Yson=findd(x);
        int Rson=findd(Y);
        int B=tree[x].ch[Yson^1];
        connect(B,Y,Yson);
        connect(Y,x,Yson^1);
        connect(x,R,Rson);
        update(Y),update(x);
    }
    inline void splay(register int x,register int to)
    {
        to=tree[to].fa;
        while(tree[x].fa!=to)
        {
            int y=tree[x].fa;
            if(tree[y].fa==to)
                rotate(x);
            else if(findd(x)==findd(y))
                rotate(y),rotate(x);
            else
                rotate(x),rotate(x);
        }
    }
    inline int newpoint(register int v,register int fa)
    {
        tree[++tot].fa=fa;
        tree[tot].v=v;
        tree[tot].sum=1;
        return tot;
    }
    inline void Insert(register int x)
    {
        int now=root;
        if(root==0)
        {
            newpoint(x,0);
            root=tot;
        }
        else
        {
            while(19260817)
            {
                ++tree[now].sum;
                int nxt=x<tree[now].v?0:1;
                if(!tree[now].ch[nxt])
                {
                    int p=newpoint(x,now);
                    tree[now].ch[nxt]=p;
                    splay(p,root);
                    return;
                }
                now=tree[now].ch[nxt];
            }
        }
    }
    inline int find(register int v)
    {
        int now=root;
        while(19260817)
        {
            if(tree[now].v==v)
            {
                splay(now,root);
                return now;
            }
            int nxt=v<tree[now].v?0:1;
            if(!tree[now].ch[nxt])
                return 0;
            now=tree[now].ch[nxt];
        }
    }
    inline void delet(register int x)
    {
        int pos=find(x);
        if(!pos)
            return;
        if(!tree[pos].ch[0]&&!tree[pos].ch[1])
            root=0;
        else if(!tree[pos].ch[0])
        {
            root=tree[pos].ch[1];
            tree[root].fa=0;
        }
        else
        {
            int left=tree[pos].ch[0];
            while(tree[left].ch[1])
                left=tree[left].ch[1];
            splay(left,tree[pos].ch[0]);
            connect(tree[pos].ch[1],left,1);
            connect(left,0,1);
            update(left);
        }
    }
    inline int lower(register int v)
    {
        int now=root;
        int ans=-inf;
        while(now)
        {
            if(tree[now].v<v&&tree[now].v>ans)
                ans=tree[now].v;
            if(v>tree[now].v)
                now=tree[now].ch[1];
            else
                now=tree[now].ch[0];
        }
        return ans;
    }
    inline int upper(register int v)
    {
        int now=root;
        int ans=inf;
        while(now)
        {
            if(tree[now].v>v&&tree[now].v<ans)
                ans=tree[now].v;
            if(v<tree[now].v)
                now=tree[now].ch[0];
            else
                now=tree[now].ch[1];
        }
        return ans;
    }
    int a[1000005];
    int main()
    {
        Insert(inf);
        Insert(-inf);
        int opt=read(),ans1=0,ans2=0;
        while(opt!=-1)
        {
            if(opt==1)
            {
                int w=read(),c=read();
                if(!find(c))
                {
                    ans1+=w,ans2+=c;
                    a[c]=w;
                    Insert(c);
                }
            }
            else if(opt==2)
            {
                int c=lower(inf);
                if(c!=-inf)
                {
                    ans1-=a[c],ans2-=c;
                    a[c]=0;
                    delet(c);
                }
            }
            else
            {
                int c=upper(-inf);
                if(c!=inf)
                {
                    ans1-=a[c],ans2-=c;
                    a[c]=0;
                    delet(c);
                }
            }
            opt=read();
        }
        write(ans1),putchar(' '),write(ans2);
        return 0;
     } 
    
  • 相关阅读:
    android之ConnectivityManager简介,网络连接状态
    SPOJ SUBLEX 7258. Lexicographical Substring Search
    poj 2417 Discrete Logging(A^x=B(mod c),普通baby_step)
    设计模式汇总
    微信公众平台预研小结
    Android开发之Handler的用法(源码分享)
    通过ccb(CocosBuilder)文件生成cocos2dx代码
    图像处理之错切变换
    combobox自己主动提示组件加入无选中项清空功能
    php 二维数组传递给 js 问题解决记录
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10017405.html
Copyright © 2011-2022 走看看