Ice-cream Tycoon SGU - 311 splay

splay参考:http://blog.csdn.net/acm_fighting/article/details/52331833

Splay中有一些常用的操作和一些很容易犯的bug

先来记录一下容易写错的地方

    新建结点(或者连续一段,特指在key_value的位置插入和删除)或者删除结点(或者连续一段)的时候需要pushup(ch[root][1]),pushup(root)
    申请一个新的结点的时候注意更新与这个点所有相关的变量,比如是维护最小值,不仅要更新val[now],还要更新minv[now]
    如果有区间加的时候,你需要查询Splay上某个点的值,你不能直接输出val[now],应该先把这个点旋转到根
    如果需要知道某个值在Splay中的位置,可以用一个map映射
    调用get_kth,get_min,get_max这些函数时,要把调用的这个点旋转到根
    插入的时候要进行旋转,这样才能保证时间复杂度logn

题目:https://vjudge.net/problem/SGU-311
博客:http://blog.csdn.net/pro_space/article/details/47008961

 题意:一个商店,有两种操作:(1)ARRIVE n c表示进货n个,每个c元。(2)BUY n t表示一个买货的人要买n个,一共拿了t元钱。如果现在店里的货的数量大于等于n且最便宜的n个的价格小于等于t则将最便宜的卖给他。否则不卖。

思路:离线的线段树,我们以价格作为结点,然后离散化,好久没做,注意的是优先处理最小的n个

线段树代码:https://vjudge.net/solution/3657190
只能说又写炸了.

#include<bits/stdc++.h>

using namespace std;
#define MP make_pair
#define N 100005
#define LL long long
#define pb push_back
#define fi first
#define se second
#define pii pair<int, int>
#define md ((ll+rr)>>1)
#define ls (i<<1)
#define rs ((i<<1)|1)
#define lson ls,ll,md
#define rson rs,md+1,rr

struct Q{
    char op[10];
    int num;
    LL c;
}q[N];
LL san[N];
LL sum[N<<2];
int num[N<<2],lazy[N<<2],L[N<<2],R[N<<2];
void up(int i){
    sum[i]=sum[ls]+sum[rs];
    num[i]=num[ls]+num[rs];
}
void down(int i){
    if(lazy[i]){
        lazy[ls]=lazy[rs]=lazy[i];
        sum[ls]=sum[rs]=0;
        num[ls]=num[rs]=0;
        lazy[i]=0;
        return;
    }
}
void build(int i,int ll,int rr){
    L[i]=ll;R[i]=rr;
    lazy[i]=0;
    if(ll==rr){
        lazy[i]=0;
        sum[i]=num[i]=0;return;
    }
    build(lson),build(rson);
    up(i);
}
void add(int i,int cnt,LL c){
    if(san[L[i]]==c&&san[R[i]]==c){
        sum[i]+=c*cnt;
        num[i]+=cnt;return;
    }
    down(i);
    if(c<=san[R[ls]])add(ls,cnt,c);
    else add(rs,cnt,c);
    up(i);
}
LL query(int i,int cnt){
    if(L[i]==R[i]){return 1LL*cnt*san[L[i]];}
    down(i);
    if(num[ls]>=cnt)return query(ls,cnt);
    else return sum[ls]+query(rs,cnt-num[ls]);
    up(i);
}

void clear(int i,int cnt){
    if(L[i]==R[i]){
        num[i]-=cnt;
        sum[i]=num[i]*L[i];
        return;
    }
    down(i);
    if(num[ls]>=cnt)clear(ls,cnt);
    else {
        clear(rs,cnt-num[ls]);
        lazy[ls]=1;
        sum[ls]=num[ls]=0;
    }
    up(i);
}
void show(int i){
    if(L[i]==R[i]){
        printf("%d ",sum[i]);
        return;
    }
    show(ls);show(rs);
}

int main(){
    int n=1;
    int tot=0;
    while(~scanf("%s%d%lld",q[n].op,&q[n].num,&q[n].c)){
        san[++tot]=q[n].c;
        ++n;
    }n--;
    sort(san+1,san+1+tot);
    tot=unique(san+1,san+1+tot)-san-1;
    build(1,1,tot);
    for(int i=1;i<=n;++i){
        if(q[i].op[0]=='A'){
            add(1,q[i].num,q[i].c);
        }
        else {
            if(query(1,q[i].num)>q[i].c)puts("UNHAPPY");
            else {
                clear(1,q[i].num);puts("HAPPY");
            }
        }
        //show(1);puts("");
    }
}

splay代码:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值