[HNOI2002]营业额统计

本文深入探讨了Treap数据结构的实现原理及其在前驱后继查询问题中的高效应用。通过具体代码示例,详细讲解了如何利用Treap进行插入操作,并实现对有序集合中元素的快速查找。文章提供了完整的C++实现代码,包括节点更新、左旋右旋调整、插入及查询算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

treap板子题。

前驱后继查询。

代码:

#include<ctime>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define N 33000
int n,a;
int rt,tot;
struct Treap
{
    int ls,rs;
    int siz,w,rnd,v;
}tr[N];
void update(int u)
{
    tr[u].siz = tr[tr[u].ls].siz + tr[tr[u].rs].siz + tr[u].w;
}
void lturn(int &x)
{
    int y = tr[x].rs;
    tr[x].rs = tr[y].ls;
    tr[y].ls = x;
    tr[y].siz = tr[x].siz;
    update(x);
    x=y;
}
void rturn(int &x)
{
    int y = tr[x].ls;
    tr[x].ls = tr[y].rs;
    tr[y].rs = x;
    tr[y].siz = tr[x].siz;
    update(x);
    x=y;
}
void insert(int &k,int x)
{
    if(!k)
    {
        k = ++tot;
        tr[k].siz = tr[k].w = 1;
        tr[k].v = x,tr[k].rnd = rand();
        return ;
    }
    tr[k].siz++;
    if(tr[k].v==x)
    {
        tr[k].w++;
        return ;
    }else if(tr[k].v<x)
    {
        insert(tr[k].rs,x);
        if(tr[tr[k].rs].rnd<tr[k].rnd)lturn(k);
    }else
    {
        insert(tr[k].ls,x);
        if(tr[tr[k].ls].rnd<tr[k].rnd)rturn(k);
    }
}
int ans = 0;
void qq(int u,int x)
{
    if(!u)return ;
    if(tr[u].v<=x)
    {
        ans = tr[u].v;
        qq(tr[u].rs,x);
    }else qq(tr[u].ls,x);
}
void hj(int u,int x)
{
    if(!u)return ;
    if(tr[u].v>=x)
    {
        ans = tr[u].v;
        hj(tr[u].ls,x);
    }else hj(tr[u].rs,x);
}
int main()
{
    srand(time(NULL));
    scanf("%d",&n);
    int as = 0;
    insert(rt,-2000005);
    insert(rt,2000005);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a);
        if(i==1)
        {
            insert(rt,a);
            as+=a;
            continue;
        }
        ans = -2000005;
        qq(rt,a);
        int tmp = a-ans;
        ans = 2000005;
        hj(rt,a);
        tmp = tmp<(ans-a)?tmp:(ans-a);
        as+=tmp;
        insert(rt,a);
    }
    printf("%d\n",as);
    return 0;
}

 

转载于:https://www.cnblogs.com/LiGuanlin1124/p/9593960.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值