Hihocoder 1329(splay)
Problem 平衡树 Splay
题目大意
维护一个数列,支持三种操作。
操作1:添加一个数x。
操作2:询问不超过x的最大的数。
操作三:删除大小在区间【a,b】内的数。
解题分析
和上一题相比,多了一个删除的操作。
首先将a的前驱节点x旋转到根,然后将b的后驱节点y旋转到x的右孩子,这样所有大小在【a,b】内的数均位于y的左子树内,直接将其删掉就可以了。
为了防止找不到x和y,在初始化时向树中插入一个极大值和一个极小值。
参考程序
- #include <bits/stdc++.h>
- using namespace std;
- struct node{
- int val;
- node *left,*right,*father;
- node(int val_=,node* father_=NULL,node* left_=NULL,node* right_=NULL)
- {
- val=val_; father=father_; left=left_; right=right_;
- }
- }*rt,*t1,*t2;
- void search(node *now)
- {
- cout<<now<<" "<<now->val<<" "<<now->left<<" "<<now->right<<" "<<now->father<<endl;
- if (now->left) search(now->left);
- if (now->right) search(now->right);
- }
- void pushup(node *x)
- {
- }
- void right(node* x,node* &rt)
- {
- node *y=x->father,*z=y->father;
- if (y==rt) rt=x;
- else if (z->left==y) z->left=x; else z->right=x; //需要判断是左右孩子
- x->father=z; y->father=x; if (x->right) x->right->father=y; //防止对空指针进行操作
- y->left=x->right; x->right=y;
- pushup(y); pushup(x);
- }
- void left(node* x,node* &rt)
- {
- node *y=x->father,*z=y->father;
- if (y==rt) rt=x;
- else if (z->left==y) z->left=x; else z->right=x;
- x->father=z; y->father=x; if (x->left) x->left->father=y;
- y->right=x->left; x->left=y;
- pushup(y); pushup(x);
- }
- void splay(node* x,node* &rt)
- {
- while (x!=rt)
- {
- node *y=x->father, *z=y->father;
- if (y==rt)
- {
- if (x==y->left) right(x,rt);
- else left(x,rt);
- }
- else
- {
- if (y==z->left)
- if (x==y->left) { right(y,rt); right(x,rt); }
- else { left(x,rt); right(x,rt); }
- else
- if (x==y->right) { left(y,rt); left(x,rt); }
- else { right(x,rt); left(x,rt); }
- }
- }
- }
- void insert(int val,node* &now,node *last)
- {
- if (now==NULL)
- {
- now=new node(val,last);
- splay(now,rt);
- return;
- }
- if (val < now->val) insert(val,now->left,now); else //else还是要加的 返回的时候树的形态已经改变了
- if (val > now->val) insert(val,now->right,now);
- }
- int get(int val,node *x)
- {
- int res=-<<;
- while (x!=NULL)
- {
- if (x->val>val) x=x->left;
- else
- {
- res=max(res,x->val);
- x=x->right;
- }
- }
- return res;
- }
- void find_1(int val,node *x)
- {
- if (x==NULL) return;
- if (x->val>=val) find_1(val,x->left);
- else {t1=x; find_1(val,x->right);}
- }
- void find_2(int val,node *x)
- {
- if (x==NULL) return;
- if (x->val<=val) find_2(val,x->right);
- else {t2=x; find_2(val,x->left);}
- }
- void work(int l,int r)
- {
- t1=t2=NULL;
- find_1(l,rt); splay(t1,rt);
- find_2(r,rt->right); splay(t2,rt->right);
- rt->right->left=NULL;
- }
- int main()
- {
- int n;
- rt=NULL;
- scanf("%d",&n);
- insert(<<,rt,NULL); insert(-<<,rt,NULL);
- for (int i=;i<=n;i++)
- {
- char s[]; int x,y;
- scanf("%s%d",s,&x);
- if (s[]=='I') insert(x,rt,NULL);
- if (s[]=='Q') cout<<get(x,rt)<<endl;
- if (s[]=='D')
- {
- scanf("%d",&y);
- if (x>y) swap(x,y);
- work(x,y);
- }
- }
- }
Hihocoder 1329(splay)的更多相关文章
- Hihocoder 1325 (splay)
Problem 平衡树 Treap 题目大意 维护一个数列,支持两种操作. 操作1:添加一个数x. 操作2:询问不超过x的最大的数. 解题分析 尝试了一下用指针来写splay,感觉写起来还是比较流畅的 ...
- Hihocoder 1333 (splay)
Problem 平衡树 splay2 题目大意 维护一个序列,支持四种操作: 操作1:添加一个数,编号为x,权值为y. 操作2:删除编号在区间[x,y]内的数. 操作3:将编号在区间[x,y]内的数的 ...
- Hihocoder 1329 平衡树·Splay(平衡树)
Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...
- 【BZOJ3506】排序机械臂(Splay)
[BZOJ3506]排序机械臂(Splay) 题面 神TMBZOJ没有题面,感谢SYC的题面 洛谷的题面也不错 题解 对于每次旋转的物体 显然可以预处理出来 现在只要模拟旋转操作就行了 至于在哪里放标 ...
- 【BZOJ1500】【NOI2005】维修数列(Splay)
[BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...
- 【BZOJ1862】[ZJOI2006]游戏排名系统 (Splay)
[BZOJ1862][ZJOI2006]游戏排名系统 (Splay) 题面 BZOJ 洛谷 题解 双倍经验题
- 【BZOJ1056】[HAOI2008]排名系统(Splay)
[BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...
- 【BZOJ2329】括号修复(Splay)
[BZOJ2329]括号修复(Splay) 题面 BZOJ 洛谷 题解 本来想着用线段树来写 但是有一个区间翻转 所以不能用线段树了,就只能用平衡树 然后直接\(Splay\)就好了 注意一下几个标记 ...
- P3391 【模板】文艺平衡树(Splay)新板子
P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...
随机推荐
- (博弈论)51NOD 1066 Bash游戏
有一堆石子共有N个.A B两个人轮流拿,A先拿.每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N和K,问最后谁能赢得比赛. 例如N = 3 ...
- 使用Redis存储Nginx+Tomcat负载均衡集群的Session
配置Tomcat的session共享可以有三种解决方案: 第一种是以负载均衡服务器本身提供的session共享策略,每种服务期的配置是不一样的并且nginx本身是没有的. 第二种是利用web容器本身的 ...
- PHP定义字符串时单引号和双引号的区别
一般用单引号或双引号标识一个字符串.单引号串与双引号串,在PHP中的处理是不同的.双引号中的内容可以被解释并被替换,单引号串中的内容则被作为普通字符处理. 例如: $str=6; echo " ...
- 238 Product of Array Except Self 除自身以外数组的乘积
一个长度为 n 的整形数组nums,其中 n > 1,返回一个数组 output ,其中 output[i] 等于nums中除nums[i]以外所有元素的乘积.不用除法 且在O(n)内解决这个问 ...
- [转]深入ASP.NET MVC之二:路由模块如何工作
本文转自:http://www.cnblogs.com/yinzixin/archive/2012/11/05/2754483.html 摘要: 上文分析了UrlRouting模块何时会被触发,本文重 ...
- [转]MVC4项目中验证用户登录一个特性就搞定
本文转自:http://www.mrhuo.com/Article/Details/470/A-Attribute-For-MVC4-Project-Used-To-Validate-User-Log ...
- .net面试题 2016
经典面试题2016——50题 1.面向对象语言具有——继承性——,——封装性——,——多态性—— 继承性:就是让一个类型的对象拥有另一个类型的对象的属性的方法.继承后,子类拥有父类的属性和方法. 封装 ...
- Flask Web 发送邮件单文件
import os from flask import Flask, render_template, session, redirect, url_for from flask_script imp ...
- struts2之通配符映射
系统有n多个请求时候,不可能以一个action对应一个映射.可以用通配符映射将成百上千请求简化成一个通用映射. 通配符映射规则:1.若找到多个匹配,没有通配符的将胜出. 2.若指定的动作不存在,str ...
- 在Resource中使用x:Bind
Build2015上,MS热情高涨的演示了x:Bind,一种新的Binding方式,新的方式有如下优点: 1更好的性能(内存占用,CPU占用) 2BuildTime的Binding 具体在Channe ...