首页 > 其他分享 >P2234 [HNOI2002] 营业额统计

P2234 [HNOI2002] 营业额统计

时间:2025-01-21 19:43:46浏览次数:1  
标签:营业额 int siz tr fa HNOI2002 key now P2234

P2234 [HNOI2002] 营业额统计

题目翻译:

给定 \(n\) 个数,每一个数都要统计其最小波动值,波动值的定义是当天银收额和之前某次的营收额的差的绝对值,而要求每一天最小波动值的和(第一天波动值为当天营收额)

思路:

分析题目可以发现,最小波动值就是当天营收额与之前小于它的最大营收额的差的绝对值或之前大于它的最小营收额的差的绝对值。即当天的营收额的前驱和后继。想到这里就会想到二叉搜索树,为了防止树太高被卡,于是用平衡树来维护,接下来就是直接套模板即可。

注意: 要提前在树中插入一个极大值和极小值。

完整代码:

#include<bits/stdc++.h>
#define lc(x) tr[(x)].s[0]
#define rc(x) tr[(x)].s[1]
#define fa(x) tr[(x)].fa
using namespace std;
const int N=32800;
const int INF=0x3f3f3f3f;
struct tree{
    int s[2],key,fa,siz;
    tree(){s[0]=s[1]=fa=key=siz=0;}
}tr[N];
int rt,cnt;
void clear(int x){
    lc(x)=rc(x)=fa(x)=tr[x].key=tr[x].siz=0;
}
void pushup(int x){
    tr[x].siz=tr[lc(x)].siz+tr[rc(x)].siz;
}
bool get(int x){
    return x==rc(fa(x));
}
int newnode(int key){
    tr[++cnt].key=key;
    tr[cnt].siz=1;
    return cnt;
}
void rotate(int x){
    int y=fa(x),z=fa(y),c=get(x);
    if(tr[x].s[c^1]){
        fa(tr[x].s[c^1])=y;
    }
    tr[y].s[c]=tr[x].s[c^1];
    tr[x].s[c^1]=y;
    fa(y)=x;
    fa(x)=z;
    if(z)tr[z].s[y==tr[z].s[1]]=x;
    pushup(y);
    pushup(x);
}
void splay(int x){
    for(int f=fa(x);f=fa(x),f;rotate(x)){
        if(fa(f))rotate(get(x)==get(f)?f:x);
    }
    rt=x;
}
void ins(int key){
    int now=rt,f=0;
    while(now){
        f=now;
        now=tr[now].s[key>tr[now].key];
    }
    now=newnode(key);
    fa(now)=f;
    tr[f].s[key>tr[f].key]=now;
    splay(now);
}
int pre(int key){
    int now=rt,f=0,ans=0;
    while(now){
        f=now;
        if(tr[now].key>=key){
            now=lc(now);
        }
        else{
            ans=tr[now].key;
            now=rc(now);
        }
    }
    splay(f);
    return ans;
}
int nxt(int key){
    int now=rt,f=0,ans=0;
    while(now){
        f=now;
        if(tr[now].key<=key){
            now=rc(now);
        }
        else{
            ans=tr[now].key;
            now=lc(now);
        }
    }
    splay(f);
    return ans;
}
map<int,bool>vis;
signed main(){
    long long n,ans=0;
    scanf("%lld",&n);
    ins(INF),ins(-INF);
    int val;
    scanf("%d",&val);
    ins(val);
    ans+=val;
    vis[val]=true;
    for(int i=2;i<=n;i++){
        int val;
        scanf("%d",&val);
        if(vis[val]){
            continue;
        }
        vis[val]=true;
        ins(val);
        ans+=min(abs(val-pre(val)),abs(val-nxt(val)));
    }
    printf("%lld\n",ans);
}

平衡树讲解

标签:营业额,int,siz,tr,fa,HNOI2002,key,now,P2234
From: https://www.cnblogs.com/XichenOC/p/18684326

相关文章

  • 1321. 餐馆营业额变化增长 - 力扣(LeetCode)
    1321.餐馆营业额变化增长-力扣(LeetCode)目标输入输入:营业额customer_idnamevisited_onamount1Jhon2019/1/11002Daniel2019/1/21103Jade2019/1/31204Khaled2019/1/41305Winston2019/1/51106Elvis2019/1/61407Anna2019/1/71508Maria2019/1/8809Jaze2019/1/91101Jhon2019......
  • SQL.LeetCode(1321)餐馆营业额变化增长
    表: Customer+---------------+---------+|ColumnName|Type|+---------------+---------+|customer_id|int||name|varchar||visited_on|date||amount|int|+---------------+---------+在SQL中,(customer......
  • 米斯蒂娅的营业额
    题面描述米斯蒂娅的夜雀食堂开业啦!经营时米斯蒂娅若能做出正确满足顾客词条需求的菜,即可获得一定数量的金额,小费与combo(连击)次数。combo次数越高小费倍率越高,每次获得combo,小费倍率增加0.1,即时生效于当前订单,小费倍率最高为0.5。但是,如果没能让顾客满意,不仅收不到钱,还会断combo......
  • JAVA-二维数组-要求计算出每个季度的总营业额和全年的总营业额-求指导
            二维数组的练习某商城每个季度的营业额如下:单位(万元)第一季度:22,66,44第二季度:77,33,88第三季度:25,45,65第四季度:11,66,99要求计算出每个季度的总营业额和全年的总营业额package_exercis;publicclassTwoArray{publicstaticvoidmain(S......
  • 洛谷题单指南-线性表-P2234 [HNOI2002] 营业额统计
    原题链接:https://www.luogu.com.cn/problem/P2234题意解读:要计算每一天最小波动值的和,需要对每一天求最小波动值,再求和,如果暴力法,时间复杂度在1+2+3+......+32767≈5*10^8,可能会超时。解题思路:1、暴力法:由于本题测试数据比较水,实测暴力求解直接可以AC,由于没有技术含量,不做具体......
  • P2234 [HNOI2002] 营业额统计
    P2234[HNOI2002]营业额统计题解思路对原数组排序,记录下排序前的位置。对排序后的数组构造链表。从原数组的\(n\)往\(1\)枚举,比较排序生成链表中该元素的前驱或后继与该元素差值的最小值,加入答案。在排序生成的链表中删除该元素。正确性的疑惑一开始很困惑,难道排序......
  • P2234
    乐死我了,一道需要用平衡树的算法的题,在我忘了看标签的情况下下意识用了一个普及-难度的超简单思路解决了。当然其中加入了一些半骗分半贪心性质的剪枝。总之这破算法竟然AC了就离谱,乐死我了Code#include<iostream>#include<cmath>usingnamespacestd;intb[2000005];int......
  • 营业额统计_代码开发
            ......
  • 题解 P2229 【[HNOI2002]沙漠寻宝】
    postedon2021-06-0112:15:15|under题解|source这题一看就知道是个模拟。做模拟题的时候,一定要先确保你的程序能跑出正确的结果,再去想优化时间。这道题还是很简单的,让我们开始吧:读入我们把输入离线,拿string存起来。如果不离线,那loop就会很难处理,加大难度。intn;......
  • 题解 P2276 [HNOI2002]农场的果树
    首先可以观察出一颗\(n\)个节点的二叉树,当其字典序最小的时候,其形态为一条向右偏的链,当其字典序最大的时候,是一条向左偏的链。由于每一种编码对应唯一的一颗二叉树,我们可以先建树。然后考虑树上分治,尝试以下三种方式:变大右子树的字典序变大左子树的字典序,并将右子树变成......