P2286 [HNOI2004] 宠物收养场

news/2025/1/23 20:44:36/文章来源:https://www.cnblogs.com/XichenOC/p/18688603

P2286 [HNOI2004] 宠物收养场

题目翻译:

给定 \(n\) 次操作,每次操作会添加一个元素。并且维护一个集合,若当前添加的元素与集合中元素种类相同,则直接添加,若不相同这要将最终答案加上给元素与集合中元素的差的绝对值的最小值,并删除对应的集合中的元素。(特别注意:若有两个元素与添加元素的差相同,则删除较小的那个)

思路:

若要找到一个与添加元素最接近的元素,且可以随意删除添加,很容易想到平衡树。我们维护一个平衡树,在查询的时候直接找前驱和后继,求最小值然后,删除即可。对于两种不同种类的元素,我们只需要用一个变量 \(op\) 维护当前集合中的元素类型,并用 \(cnt\) 变量维护当前集合中元素个数,这样每次添加元素时,若 \(cnt=0\) 就给 \(op\) 赋值为当前元素类型,即可。

完整代码:

#include<bits/stdc++.h>
#define fa(x) tr[(x)].fa
#define lc(x) tr[(x)].s[0]
#define rc(x) tr[(x)].s[1]
using namespace std;
const int N=1e5+10;
const int P=1000000;
struct tree{int s[2],fa,siz,key;tree(){s[0]=s[1]=fa=siz=key=0;}
}tr[N];
int rt,idx;
void pushup(int x){tr[x].siz=tr[lc(x)].siz+tr[rc(x)].siz+1;
}
int newnode(int key){tr[++idx].key=key;tr[idx].siz=1;return idx;
}
int get(int x){return x==rc(fa(x));
}
void clear(int x){lc(x)=rc(x)=fa(x)=tr[x].siz=tr[x].key=0;
}
void rotate(int x){int y=fa(x),z=fa(y),c=get(x);if(tr[x].s[c^1])tr[tr[x].s[c^1]].fa=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==rc(z)]=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(x)?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);tr[f].s[key>tr[f].key]=now;fa(now)=f;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;
}
void del(int key){int now=rt,f=0;while(now && key!=tr[now].key){f=now;now=tr[now].s[key>tr[now].key];}if(!now){splay(f);return;}splay(now);int cur=lc(now);if(!cur){rt=rc(now);fa(rt)=0;clear(now);return;}while(rc(cur)){cur=rc(cur);}fa(rc(now))=cur;rc(cur)=rc(now);fa(lc(now))=0;clear(now);pushup(cur);splay(cur);
}
int main(){ins(+214748364);ins(-214748364);int n;scanf("%d",&n);int op,w,now,ans=0,cnt=0;for(int i=1;i<=n;i++){scanf("%d%d",&op,&w);if(cnt==0){now=op;}if(op==now){ins(w);cnt++;}else{int w1=pre(w),w2=nxt(w);//cout<<w1<<" "<<w2<<endl;if(abs(w-w1)<=abs(w-w2)){ans+=abs(w-w1);ans%=P;cnt--;del(w1);}else{ans+=abs(w-w2);ans%=P;cnt--;del(w2);}}}printf("%d",ans);
}

平衡树讲解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873846.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025多校冲刺省选模拟赛7

2025多校冲刺省选模拟赛7\(T1\) A. 三色卡(card) \(0pts\)如果存在一个小矩形和大矩形的大小相同,此时另外两个矩形可以任意放,贡献是容易计算的。否则至少需要一个小矩形覆盖大矩形的两个角,通过交换长、宽钦定完全覆盖行的矩形比完全覆盖列的矩形的数量多。完全覆盖行的矩…

重试机制与 CompletableFuture 拓展

重试机制与 CompletableFuture 拓展 禁止转载。 本文旨在讨论重试机制的特点和策略,分析常用重试类库的实现,讨论为 CompletableFuture 添加重试机制的方法。文章首发同名公众号,欢迎关注。 重试示例 以下是一个常见的使用异步重试的例子,当我们需要重试功能时,只需调用 r…

DL00765-光伏故障检测高分辨率无人机热红外图像细粒度含数据集4000+张

光伏发电作为清洁能源的重要组成部分,近年来得到了广泛应用。然而,随着光伏电站规模的扩大,光伏组件在运行过程中可能会出现各种故障,如热斑、遮挡、接线盒故障等。这些故障不仅会影响光伏电站的发电效率,还可能导致更严重的安全隐患。因此,准确、及时地检测并分类这些故…

VMware安装RHEL7.9

VMware安装 可以选择官网下载或者使用其他网盘资源下载。 需要注意的是,现在官网下载需要注册其账号。 下面是安装的详细步骤: 1.找到文件所在路径。双击打开之后,可能会出现环境初始化重启。重启即可。然后再次双击打开此软件。2.勾选《我接受许可协议中的条款》。3.选择安…

【二叉树】用数组给出二叉树层序遍历序列,建树以及遍历问题

传递悄悄话层序遍历数组形式的下标如下#include <algorithm> #include <cstring> #include <iostream>using namespace std;const int N = 1010, M = N * 2;int n; int h[N], e[M], ne[M], idx; int v[N], dist[N]; bool st[N];void add(int a, int b) {e[id…

关闭 Visual Studio 2022 的 Browser Link 功能

http://blog.tool90.com/330.html什么是 Browser Link 功能? Browser Link 是 Visual Studio 的一个功能,它允许 Visual Studio 与正在运行的 ASP.NET 应用程序建立一个实时通信通道。这意味着您可以在不刷新浏览器的情况下立即查看代码更改的效果。这个功能在进行前端开发时…

2025dsfz集训Day11:数位DP、状态压缩DP、单调队列优化DP

Day11:数位DP、状压DP、单调队列优化DP 经典题目:AccodersP2195 |【一本通提高数位动态规划】Amount of Degrees 题意: 求出区间 \([x,y]\) 中满足下面条件的所有的数:这个数 \(x\) 可以用 \(k\) 个不相等的 \(b\) 的整数幂之和。 首先这个区间是满足区间减法的。因此我们可…

PO报错

这个报错是报文结构不匹配导致,找了好久的问题--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------…

2025dsfz集训Day11: 单调队列优化DP

单调队列优化DP 单调队列队列是单调的,递增或递减 只能在队首或者队尾进行操作 队列中维护所有在窗口中的元素,有一些元素是没用的,以区间最大值为例:所以从左到右尝试加入队列,弹出队尾比当前数更小的元素,弹出队首已经出窗口的元素,再队尾压入当前数 这样,队首就是窗口…

必应搜索中,当地区设置为美国时出现的异常(未解决)

描述 在设置中,设置地区。加载时,会警告如下: An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing.这个大致的意思是,allow-scripts允许运行脚本,allow-same-origin视为和宿主网页同源。 具体的影响不清…

做抖音矩阵是否需要很多台手机?

做抖音矩阵是否需要很多台手机?做抖音矩阵不一定要很多台手机,可依据不同情况选择合适方式: 使用多台手机 优势:物理隔离确保账号间完全独立,极大降低因设备关联导致的风险。比如,若一台手机上的账号因违规操作被封,不会影响其他手机上的账号。同时,多台手机能同时进行…

【Neo4j知识图谱数据库】入门

在当今大数据和人工智能的时代,知识图谱作为一种高效的数据表示和查询方式,逐渐受到广泛关注。本文将带大家从入门到精通,了解知识图谱及其存储工具Neo4j的方方面面,包括知识图谱的介绍、Neo4j的特点、安装步骤、具体的使用方法(创建、查询),以及Cypher查询语言的详细讲…