P2073 送花(Treap维护双权值)

 

小明准备给小红送一束花,以表达他对小红的爱意。他在花店看中了一些花,准备用它们包成花束。

这些花都很漂亮,每朵花有一个美丽值W,价格为C。

小明一开始有一个空的花束,他不断地向里面添加花。他有以下几种操作:

操作 含义

1 W C 添加一朵美丽值为W,价格为C的花。

3 小明觉得当前花束中最便宜的一朵花太廉价,不适合送给小红,所以删除最便宜的一朵花。

2 小明觉得当前花束中最贵的一朵花太贵,他心疼自己的钱,所以删除最贵的一朵花。

-1 完成添加与删除,开始包装花束

若删除操作时没有花,则跳过删除操作。

如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。

请你帮小明写一个程序,计算出开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。

题解:

全程用Treap维护即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
const int inf=1e9;
typedef long long ll;
int w,c;
int op;
int sum;
struct Treap_tree {
    int ch[2];
    int v;//价格 
    int w;//魅力值 
    int dat;
    int size;
    int cnt;
}t[maxn];
int tot;
int root;
int newNode (int v,int w) {
    tot++;
    t[tot].v=v;
    t[tot].w=w;
    t[tot].dat=rand();
    t[tot].size=1;
    t[tot].cnt=1;
    return tot;
}
void pushup (int x) {
    t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
}
void build () {
    root=newNode(-inf,-inf);
    t[root].ch[1]=newNode(inf,inf);
    pushup(root);
}
void rotate (int &id,int d) {
    int tt=t[id].ch[d^1];
    t[id].ch[d^1]=t[tt].ch[d];
    t[tt].ch[d]=id;
    id=tt;
    pushup(t[id].ch[d]);
    pushup(id);
}
void ins (int &id,int v,int w) {
    if (!id) {
        id=newNode(v,w);
        return;
    } 
    if (v==t[id].v) return;
    else {
        ins(t[id].ch[v>t[id].v],v,w);
        if (t[id].dat<t[t[id].ch[v>t[id].v]].dat)
            rotate(id,v<t[id].v);
    }
    pushup(id);
}
void remove (int &id,int v) {
    if (!id) return;
    if (v==t[id].v) {
        if (t[id].ch[0]||t[id].ch[1]) {
            if (!t[id].ch[1]||t[t[id].ch[0]].dat>t[t[id].ch[1]].dat) {
                rotate(id,1);
                remove(t[id].ch[1],v);
            }
            else {
                rotate(id,0);
                remove(t[id].ch[0],v);
            }
            pushup(id);
        } 
        else
            id=0;
        return;
    }
    remove(t[id].ch[v>t[id].v],v);
    pushup(id);
}
int kth (int id,int k) {
    if (!id) return inf;
    if (k<=t[t[id].ch[0]].size)
        return kth(t[id].ch[0],k);
    else if (k<=t[t[id].ch[0]].size+t[id].cnt)
        return t[id].v;
    else
        return kth(t[id].ch[1],k-t[t[id].ch[0]].size-t[id].cnt);
}
pair<ll,ll> bfs (int id) {
    ll ans1=0,ans2=0;
    queue<int> q;
    q.push(id);
    while (!q.empty()) {
        int u=q.front();
        q.pop();
        ans1+=t[u].v;
        ans2+=t[u].w;
        if (t[u].ch[0]) q.push(t[u].ch[0]);
        if (t[u].ch[1]) q.push(t[u].ch[1]);
    } 
    return make_pair(ans1,ans2);
}
int main () {
    sum=0;
    while (1) {
        scanf("%d",&op);
        if (op==1) {
            scanf("%d%d",&w,&c);
            ins(root,c,w);
        }
        if (op==2) {
            sum=t[root].size;
            int Max=kth(root,sum);
            remove(root,Max);
        }
        if (op==3) {
            int Min=kth(root,1);
            remove(root,Min);
        }
        if (op==-1) break;
    }
    pair<ll,ll> ans=bfs(root);
    printf("%lld %lld\n",ans.second,ans.first);
} 

 

posted @ 2020-08-05 00:04  zlc0405  阅读(104)  评论(0编辑  收藏  举报