poj3481 splaytree模板题
找不到错在哪里,先留着吧
/*
splay是以键值排序的!
三个操作:1 a b,z增加键值为b的点,值为a
2,查询最大值
3,查询最小值
需要的操作:rotate,splay,insert,findx,delete
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1000005
int pre[maxn],ch[maxn][],size[maxn],key[maxn],num[maxn],root,tot; void newnode(int &r,int fa,int k,int val){
r=++tot;
pre[r]=fa;
ch[r][]=ch[r][]=;
key[r]=k;
num[r]=val;
}
void pushup(int r){
size[r]=;
if(ch[r][]) size[r]+=size[ch[r][]];
if(ch[r][]) size[r]+=size[ch[r][]];
size[r]+=;
}
void rotate(int x,int kind){//0左旋,1右旋
int fa=pre[x];
ch[fa][!kind]=ch[x][kind];
pre[ch[x][kind]]=fa;
if(pre[fa])
ch[pre[fa]][ch[pre[fa]][]==fa]=x;
pre[x]=pre[fa];
pre[fa]=x;
ch[x][kind]=fa;
pushup(fa);
pushup(x);
}
void splay(int r,int goal){
while(pre[r]!=goal){
if(pre[pre[r]]==goal) rotate(r,ch[pre[r]][]==r);
else {
int fa=pre[r];
int kind=ch[pre[fa]][]==fa;//fa的旋转方向,与fa所在子树相反
if(ch[fa][kind]==r){rotate(r,!kind);rotate(r,kind);}
else{rotate(fa,kind);rotate(r,kind);}
}
}
if(goal==) root=r;
pushup(r);
}
void init(){
root=tot=;
ch[root][]=ch[root][]=pre[root]=size[root]=num[root]=key[root]=;
}
void insert(int k,int val){//插入键值为k的结点
int r=root;
if(r==) {newnode(root,,k,val);pushup(root);return;}
while(ch[r][key[r]<k]) r=ch[r][key[r]<k];
newnode(ch[r][key[r]<k],r,k,val);
splay(ch[r][key[r]<k],);//把k提上去作为根
pushup(r);
}
int getth(int r,int pos){//返回第pos个结点的
int t=size[ch[r][]]+;
if(pos==t) return r;
else if(pos<t) getth(ch[r][],pos);
else getth(ch[r][],pos-t);
}
void remove(){//删除根节点
if(ch[root][]==){root=ch[root][];pre[root]=;}//只有右子树
else {
int tmp=getth(ch[root][],size[ch[root][]]);
splay(tmp,root);
ch[tmp][]=ch[root][];
pre[ch[root][]]=tmp;
root=tmp;
pre[root]=;
}
pushup(root);
}
int main(){
int op,k,p;
init();//建立一颗空树
while(scanf("%d",&op)&&op){
if(op==){//最大值
if(root==) {
puts("");
continue;
}
int ans=getth(root,size[root]);
splay(ans,);
printf("%d\n",num[ans]);
remove();
//debug();
}
else if(op==){
if(root==){
puts("");
continue;
}
int ans=getth(root,);
splay(ans,);
printf("%d\n",num[ans]);
remove();
//debug();
}
else {
scanf("%d%d",&k,&p);
insert(p,k);//p是关键字,k是值
//debug();
}
}
return ;
}
终于过了:和上面做法有些不同,找到最大或最小的点,将其作为根,同时将前驱后缀提取出来当做子树
/* */
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 100005
#define inf 0x3f3f3f3f
int pre[maxn],ch[maxn][],nums[maxn],keys[maxn],size[maxn],tot,root; inline void newnode(int &r,int fa,int k,int val){
r=++tot;
ch[r][]=ch[r][]=;
pre[r]=fa;
size[r]=;
nums[r]=val;
keys[r]=k;
}
void init(){
tot=root=;
pre[root]=ch[root][]=ch[root][]=size[root]=;
}
inline void pushup(int x){
size[x]=size[ch[x][]]+size[ch[x][]]+;
}
inline void rotate(int x,int kind){
int fa=pre[x];
ch[fa][!kind]=ch[x][kind];
pre[ch[x][kind]]=fa;
pre[x]=pre[fa];
if(pre[fa])
ch[pre[fa]][ch[pre[fa]][]==fa]=x;
ch[x][kind]=fa;
pre[fa]=x;
pushup(fa);
pushup(x);
}
inline void splay(int x,int goal){
while(pre[x]!=goal){
if(pre[pre[x]]==goal) rotate(x,ch[pre[x]][]==x);
else {
int fa=pre[x];
int kind=ch[pre[fa]][]==fa;
if(ch[fa][kind]==x){
rotate(x,!kind);
rotate(x,kind);
}
else {
rotate(fa,kind);
rotate(x,kind);
}
}
}
pushup(x);
if(goal==) root=x;
}
int find(int key){
if(root==) return ;
int x=root;
while(x && keys[x]!=key)
x=ch[x][key>keys[x]];
if(x) splay(x,);
return x;
}
int prev(){
int x=ch[root][];
if(x==) return ;//ÎÞǰÇý
while(ch[x][])
x=ch[x][];
return x;
}
int succ(){
int x=ch[root][];
if(x==) return ;//ÎÞºó¼Ì
while(ch[x][])
x=ch[x][];
return x;
}
void insert(int key,int num){
if(root==) {newnode(root,,key,num);return;}
int x=root,lastx=;
while(x){
lastx=x;
x=ch[x][key>keys[x]];
}
newnode(x,lastx,key,num);
ch[lastx][key>keys[lastx]]=x;
pre[x]=lastx;
splay(x,);
} void del(int key){
int x=find(key);
if(x==) return;
int tmp1=prev(),tmp2=succ();
if(!tmp1 && !tmp2){root=;return;}
if(!tmp1){//Ö»ÓÐÓÒ×ÓÊ÷
splay(tmp2,);
ch[tmp2][]=;
pushup(tmp2);
return;
}
if(!tmp2){//Ö»ÓÐ×ó×ÓÊ÷
splay(tmp1,);
ch[tmp1][]=;
pushup(tmp1);
return;
}
splay(tmp1,);
splay(tmp2,tmp1);
ch[tmp2][]=;
pushup(tmp2);pushup(tmp1);
}
int getth(int x,int pos){
if(root==) return ;
int t=size[ch[x][]]+;
if(pos==t) return x;
else if(pos<t) return getth(ch[x][],pos);
else return getth(ch[x][],pos-t);
}
int main(){
int p,key,num,x;
while(scanf("%d",&p)&&p){
switch(p){
case :
scanf("%d%d",&num,&key);
insert(key,num);
break;
case :
x=getth(root,size[root]);
if(x){
printf("%d\n",nums[x]);
del(keys[x]);
}
else printf("0\n");
break;
case :
x=getth(root,);
if(x){
printf("%d\n",nums[x]);
del(keys[x]);
}
else printf("0\n");
}
}
return ;
}
poj3481 splaytree模板题的更多相关文章
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- HDU 2222 AC自动机模板题
题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...
- POJ2774 & 后缀数组模板题
题意: 求两个字符串的LCP SOL: 模板题.连一起搞一搞就好了...主要是记录一下做(sha)题(bi)过程心(cao)得(dan)体(xin)会(qing) 后缀数组概念...还算是简单的,过程 ...
- HDU 1251 Trie树模板题
1.HDU 1251 统计难题 Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #incl ...
- HDU-3549 最大流模板题
1.HDU-3549 Flow Problem 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 3.总结:模板题,参考了 http://ww ...
- HDU 4280:Island Transport(ISAP模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=4280 题意:在最西边的点走到最东边的点最大容量. 思路:ISAP模板题,Dinic过不了. #include & ...
- HDU-2222 Keywords Search(AC自动机--模板题)
题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include< ...
- Dancing Link --- 模板题 HUST 1017 - Exact cover
1017 - Exact cover Problem's Link: http://acm.hust.edu.cn/problem/show/1017 Mean: 给定一个由0-1组成的矩阵,是否 ...
- AC自动机 - 多模式串匹配问题的基本运用 + 模板题 --- HDU 2222
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
随机推荐
- P2034 选择数字
P2034 选择数字 题目描述 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 错误日志: longlong ...
- 20190311 Windows安装ZooKeeper
1. 说明 记录过程中踩过的坑 1.1. 环境 本机环境:Win10 ZooKeeper版本:3.4.6 2. 安装 2.1. 下载 官网下载网址 2.2. 修改配置文件 复制conf目录下的zoo_ ...
- MySQL 5.6版本内存占用过高的解决办法
最近在阿里云购买了一台云服务器,因为是自己测试玩的,所以配置按最低的来了,1G内存,然后啪啪啪(指键盘声音)的安装了JDK,Tomcat,MySQL(5.6)等一系列环境,开始很爽,然后噩梦开始了: ...
- JAVA记录-SpringMVC scope属性的两种模式
singleton作用域:当把一个Bean定义设置为singleton作用域是,Spring IoC容器中只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean定义相匹配,则只 ...
- bzoj千题计划297:bzoj3629: [JLOI2014]聪明的燕姿
http://www.lydsy.com/JudgeOnline/problem.php?id=3629 约数和定理: 若n的标准分解式为 p1^k1 * p2^k2 …… 那么n的约数和= π (Σ ...
- Java基础其他
1. 二进制 进制就是进位制,常见的有二进制.十进制.十六进制等 在进制中,可用符号的数量称为基数,基数为n就称为n进制,逢n进一位: 二进制:0 1 十进制:0 1 2 3 4 5 6 7 8 9 ...
- CodeMirror 使用大全
CodeMirror是一个用于编辑器文本框textarea代码高亮javascript插件,为各种编程语言实现关键字,函数,变量等代码高亮显示,丰富的api和可扩展功能以及多个主题样式,能满足您各种项 ...
- JavaScript 无刷新修改浏览器URL地址栏
//发现地址栏已改为:newUrlvar stateObject = {}; var title = "Wow Title"; var newUrl = "/my/awe ...
- 不同数据库下的web.config中数据库连接字符串
<connectionStrings> <add name="OADBConnectionString" connectionString="Data ...
- JavaScript之判断参数的数值的详细类型
//判断是否为字符串 //返回类型: //{baseType:typeof(arg),numberType:'int','float',-1} function numberType(arg){ va ...