找不到错在哪里,先留着吧

/*
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模板题的更多相关文章

  1. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  2. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  3. POJ2774 & 后缀数组模板题

    题意: 求两个字符串的LCP SOL: 模板题.连一起搞一搞就好了...主要是记录一下做(sha)题(bi)过程心(cao)得(dan)体(xin)会(qing) 后缀数组概念...还算是简单的,过程 ...

  4. HDU 1251 Trie树模板题

    1.HDU 1251 统计难题  Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #incl ...

  5. HDU-3549 最大流模板题

    1.HDU-3549   Flow Problem 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 3.总结:模板题,参考了 http://ww ...

  6. HDU 4280:Island Transport(ISAP模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=4280 题意:在最西边的点走到最东边的点最大容量. 思路:ISAP模板题,Dinic过不了. #include & ...

  7. HDU-2222 Keywords Search(AC自动机--模板题)

    题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include< ...

  8. Dancing Link --- 模板题 HUST 1017 - Exact cover

    1017 - Exact cover Problem's Link:   http://acm.hust.edu.cn/problem/show/1017 Mean: 给定一个由0-1组成的矩阵,是否 ...

  9. AC自动机 - 多模式串匹配问题的基本运用 + 模板题 --- HDU 2222

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

随机推荐

  1. Ansible拷贝文件遇到的问题

    ansible报错Aborting, target uses selinux but python bindings (libselinux-python) aren't installed 报错内容 ...

  2. JavaSE考试前练习

    汽车租赁管理系统(CarRents)  120分钟 要求:请使用JavaEE实现一个汽车租赁管理系统,汽车租赁的属性主要包含:车牌(License).公里数(kilo).品牌(brand),租金(mo ...

  3. 动态规划之Fib数列类问题应用

    一,问题描述 有个小孩上楼梯,共有N阶楼梯,小孩一次可以上1阶,2阶或者3阶.走到N阶楼梯,一共有多少种走法? 二,问题分析 DP之自顶向下分析方式: 爬到第N阶楼梯,一共只有三种情况(全划分,加法原 ...

  4. VUE2.0 饿了吗视频学习笔记(三):VUE2.0取消了v-link

    https://gitee.com/1981633/vue_study.git 源码下载地址,随笔记动态更新中 写法如下 <div class="tab-item"> ...

  5. DHCP服务洪水攻击

    1.攻击原理 动态主机设置协议是一个局域网的网络协议,使用UDP协议工作,主要有两个用途: 为内部网络或网络服务供应商自动分配IP地址给用户,以作为内部网络管理员对所有计算机做中央管理的手段. 在正常 ...

  6. urllib和urllib2之间的区别

    urllib和urllib2都是接受URL请求的相关模块,但是提供了不同功能. urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL.这意味着 ...

  7. mongoDB - 日常操作一

    mongodb 启动方式 # 不启动认证 ./mongod --bind_ip 172.16.2.17 --port --fork --logpath=/opt/mongodb/mongodb.log ...

  8. mongodb系列~mongodb的副本集(1)

    一 简介: mongodb副本集 二 复制方式: 1 全量复制 2 增量复制三 同步检测过程:    一 正常情况下:       1 master执行语句,并将所有的修改数据库的操作以日志Oplog ...

  9. 2018-2019-2 网络对抗技术 20165227 Exp4 恶意代码分析

    2018-2019-2 网络对抗技术 20165227 Exp4 恶意代码分析 实验步骤: 使用的设备:Win7(虚拟机).kali(虚拟机) 实验一:使用如计划任务,每隔一分钟记录自己的电脑有哪些程 ...

  10. Centos7.5 防火墙设置

    Centos7.5默认使用firewalld作为防火墙 1.查看firewalld服务状态 systemctl status firewalld 2.查看firewalld的状态 firewall-c ...