【BZOJ1861】【splay】Book 书架

本文介绍了一个图书管理程序的设计方案,该程序使用Splay树来高效处理图书的插入、删除及查询等操作。文章提供了完整的代码实现,并解释了如何通过动态内存分配和节点旋转等技术优化数据结构。

Description

小 T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T 的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能 有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作, 以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。

Input

第 一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每 行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书房在最上面。 2. Bottom S——表示把编号为S的书房在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。

Output

对于每一条Ask或Query语句你应该输出一行,一个数,代表询问的答案。

Sample Input

10 10 
1 3 2 7 5 8 10 4 9 6
Query 3
Top 5
Ask 6
Bottom 3
Ask 3
Top 6
Insert 4 -1
Query 5
Query 2
Ask 2

Sample Output

2
9
9
7
5
3

Hint

数据范围


100%的数据,n,m < = 80000

 

Source

Zjoi2006
【分析】
基本是裸的splay,
找编号弄一个映射过去就好了。
动态内存分配大法好....
  1 /*
  2 唐代李白
  3 《江夏别宋之悌》
  4 楚水清若空,遥将碧海通。人分千里外,兴在一杯中。
  5 谷鸟吟晴日,江猿啸晚风。平生不下泪,于此泣无穷.
  6 */
  7 #include <iostream>
  8 #include <cstdio>
  9 #include <algorithm>
 10 #include <cstring>
 11 #include <vector>
 12 #include <utility>
 13 #include <iomanip>
 14 #include <string>
 15 #include <cmath>
 16 #include <queue>
 17 #include <assert.h>
 18 #include <map>
 19 #include <ctime>
 20 #include <cstdlib>
 21 #include <stack>
 22 #include <set> 
 23 #define LOCAL
 24 const int INF = 0x7fffffff;
 25 const int MAXN = 80000  + 10;
 26 const int maxnode = 20000 * 2 + 200000 * 20;
 27 const int MAXM = 50000 + 10;
 28 const int MAX = 100000000;
 29 using namespace std;
 30 struct Node {
 31        int siz;
 32        int val;//val代表数的编号 
 33        Node *parent, *ch[2];
 34        
 35        int cmp(){
 36            if (parent->ch[0] == this) return 0;
 37            else return 1;
 38        }
 39 }*root, mem[MAXN * 2], *book[MAXN * 2];//book为编号映射 
 40 int tot, n, m;
 41 
 42 Node *NEW(int val){
 43      Node *t = new Node;
 44      t->val = val;
 45      t->siz = 1;
 46      t->parent = t->ch[0] = t->ch[1] = NULL;
 47      return t;
 48 }
 49 void update(Node *&t){
 50      if (t == NULL) return;
 51      t->siz = 1;
 52      if (t->ch[0] != NULL) t->siz += t->ch[0]->siz;
 53      if (t->ch[1] != NULL) t->siz += t->ch[1]->siz;
 54      return ; 
 55 }
 56 void rotate(Node *t, int d){
 57      if (t->parent == NULL) return;//根就没必要旋转了
 58       
 59      Node *p = t->parent;
 60      p->ch[d ^ 1] = t->ch[d];
 61      if (t->ch[d] != NULL) t->ch[d]->parent = p;
 62      t->parent = p->parent;
 63      if (p->parent != NULL){
 64         if (p->parent->ch[1] == p) p->parent->ch[1] = t;
 65         else if (p->parent->ch[0] == p) p->parent->ch[0] = t;
 66      } 
 67      t->ch[d] = p;
 68      p->parent = t;
 69      update(p);
 70      update(t);
 71      if (root == p) root = t;
 72 }
 73 //将x旋转到y的子树,自己都不知道转成什么样子了... 
 74 void splay(Node *x, Node *y){
 75      while (x->parent != y){
 76            if (x->parent->parent == y){
 77               rotate(x, x->cmp() ^ 1);
 78            }else{
 79               Node *t = x->parent;
 80               //之字形
 81               if (t->ch[t->cmp() ^ 1] == x) rotate(x, x->cmp()^1);
 82               else rotate(t, t->cmp() ^ 1);
 83               rotate(x, x->cmp() ^ 1);
 84            }
 85            update(x);
 86      } 
 87      update(x);
 88 }
 89 //找到第k小然后splay上去 
 90 void find(Node *y, int k){
 91       Node *t = root;
 92       while (1){
 93             if (t->siz == 1) break;
 94             int c = (t->ch[0] == NULL ? 0 : t->ch[0]->siz);
 95             if (c + 1 == k) break;
 96             if (c  >= k ) t = t->ch[0];
 97             else {t = t->ch[1], k -= c + 1;}
 98       }
 99       splay(t, y);
100 }
101 //插入到第pos个位置 
102 void insert(Node *t, int pos, int val){
103      find(NULL, pos + 1);
104      find(root, pos + 2);
105      
106      Node *p = NEW(val);
107      root->ch[1]->ch[0] = p;
108      p->parent = root->ch[1];
109      book[val] = p;
110      splay(p, NULL); 
111 }
112 //找到元素val在t中是第几个 
113 int kth(Node *t, int val){
114     splay(book[val], NULL);
115     return root->ch[0]->siz; //不要忘了还有个INF在前面,哈哈哈 
116 }
117 void erase(Node *t, int pos){
118      find(NULL, pos);
119      find(root, pos + 2);
120      Node *p = root->ch[1]->ch[0];
121      p->parent = NULL;
122      root->ch[1]->ch[0] = NULL;
123      delete(p);
124 }
125 
126 void init(){
127      tot = 0;
128      root = NULL;
129      root = NEW(-INF);
130      root->ch[1] = NEW(INF);
131      root->ch[1]->parent = root;
132      update(root);
133      
134      //find(NULL, 2);
135      //printf("%d", root->val);
136      scanf("%d%d", &n, &m);
137      for (int i = 1; i <= n; i++){
138          int t;
139          scanf("%d", &t);
140          insert(root, i - 1, t);
141      }
142      //printf("%d", kth(root, 10));
143 }
144 void work(){
145      for (int i = 1; i <= m; i++){
146          char str[10];
147          scanf("%s", str);
148          if (str[0] == 'T'){//无论任何时候都有n本书
149             int t;
150             scanf("%d", &t); 
151             erase(root, kth(root, t));
152             insert(root, 0, t);
153          }else if (str[0] == 'B'){
154             int t;
155             scanf("%d", &t);
156             erase(root, kth(root, t));
157             insert(root, n - 1, t);
158          }else if (str[0] == 'A'){
159             int t;
160             scanf("%d", &t);
161             printf("%d\n", kth(root, t) - 1);
162          }else if (str[0] == 'Q'){
163             int t;
164             scanf("%d", &t);
165             find(NULL, t + 1);
166             printf("%d\n", root->val);
167          }else{//修改 
168             int s, t;
169             scanf("%d%d", &s, &t);
170             if (t == 0) continue;//不动
171             int tmp = kth(root, s);//记录s当前的位置 
172             erase(root, tmp);
173             if (t == -1) insert(root, tmp - 2, s);
174             else insert(root, tmp, s);
175          }
176      }
177 }
178 
179 int main(){
180     
181     init();
182     work();
183     return 0;
184 }
View Code

 

转载于:https://www.cnblogs.com/hoskey/p/4345606.html

数据集介绍:电力线目标检测数据集 一、基础信息 数据集名称:电力线目标检测数据集 图片数量: 训练集:2898张图片 验证集:263张图片 测试集:138张图片 总计:3299张图片 分类类别: 类别ID: 0(电力线) 标注格式: YOLO格式,包含对象标注信息,适用于目标检测任务。 数据格式:JPEG/PNG图片,来源于空中拍摄或监控视觉。 二、适用场景 电力设施监控与巡检: 数据集支持目标检测任务,帮助构建能够自动识别和定位电力线的AI模型,用于无人机或固定摄像头巡检,提升电力设施维护效率和安全性。 能源与公用事业管理: 集成至能源管理系统中,提供实时电力线检测功能,辅助进行风险 assessment 和预防性维护,优化能源分配。 计算机视觉算法研究: 支持目标检测技术在特定领域的应用研究,促进AI在能源和公用事业行业的创新与发展。 专业培训与教育: 数据集可用于电力行业培训课程,作为工程师和技术人员学习电力线检测与识别的重要资源。 三、数据集优势 标注精准可靠: 每张图片均经过专业标注,确保电力线对象的定位准确,适用于高精度模型训练。 数据多样性丰富: 包含多种环境下的电力线图片,如空中视角,覆盖不同场景条件,提升模型的泛化能力和鲁棒性。 任务适配性强: 标注格式兼容YOLO等主流深度学习框架,便于快速集成和模型开发,支持目标检测任务的直接应用。 实用价值突出: 专注于电力线检测,为智能电网、自动化巡检和能源设施监控提供关键数据支撑,具有较高的行业应用价值。
【弹簧阻尼器】基于卡尔曼滤波弹簧质量阻尼器系统噪声测量实时状态估计研究(Matlab代码实现)内容概要:本文围绕“基于卡尔曼滤波的弹簧质量阻尼器系统噪声测量与实时状态估计”展开研究,利用Matlab代码实现对系统状态的精确估计。重点在于应用卡尔曼滤波技术处理系统中存在的噪声干扰,提升对弹簧质量阻尼器系统动态行为的实时观测能力。文中详细阐述了系统建模、噪声特性分析及卡尔曼滤波算法的设计与实现过程,展示了滤波算法在抑制测量噪声、提高状态估计精度方面的有效性。同时,该研究属于更广泛的信号处理与状态估计技术应用范畴,适用于复杂动态系统的监控与控制。; 适合人群:具备一定控制系统理论基础和Matlab编程经验的高校研究生、科研人员及工程技术人员,尤其适合从事动态系统建模、状态估计与滤波算法研究的相关人员。; 使用场景及目标:①应用于机械、航空航天、自动化等领域中对振动系统状态的高精度实时估计;②为噪声环境下的传感器数据融合与状态预测提供算法支持;③作为卡尔曼滤波算法在实际物理系统中应用的教学与科研案例。; 阅读建议:建议读者结合Matlab代码实践,深入理解系统建模与滤波器设计的关键步骤,关注噪声建模与滤波参数调优对估计性能的影响,并可进一步拓展至扩展卡尔曼滤波(EKF)或无迹卡尔曼滤波(UKF)在非线性系统中的应用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值