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

/*
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. P5002 专心OI - 找祖先

    P5002 专心OI - 找祖先 给定一棵有根树(\(n \leq 10000\)),\(M \leq 50000\) 次询问, 求以 \(x\) 为 \(LCA\) 的点对个数 错误日志: 看下面 ...

  2. SQL记录-Oracle重命名表名例子

    rename table_1 to table_2

  3. Python中变量的属性以及判断方法

    1.变量的属性 在Python中,创建一个变量会给这个变量分配三种属性: id ,代表该变量在内存中的地址: type,代表该变量的类型: value,该变量的值: x = 10 print(id(x ...

  4. JAVA单链表的实现-不带头结点且没有尾指针

    本程序采用JAVA语言实现了线性表的链式实现.首先定义了线性表的接口ListInterface,然后LList类实现了ListInterface完成了链表的实现. 本实现中,链表是不带表头结点的,且有 ...

  5. spring boot(十一):Spring boot中mongodb的使用

    mongodb简介 传统的关系数据库一般由数据库(database).表(table).记录(record)三个层次概念组成, MongoDB是由数据库(database).集合(collection ...

  6. 关于JS事件冒泡与JS事件代理(事件委托)

    连接:https://blog.csdn.net/supercoooooder/article/details/52190100 核心代码: <ul id="parentUl" ...

  7. Python之print(args)与sys.stdout.write(string)使用总结

    一.sys.stdout.write(string) import sys; # sys.stdout.write(): # 1.默认不换行 # 2.参数必须是字符串 # demo 01 x = &q ...

  8. 第19月第8天 斯坦福大学公开课机器学习 (吴恩达 Andrew Ng)

    1.斯坦福大学公开课机器学习 (吴恩达 Andrew Ng) http://open.163.com/special/opencourse/machinelearning.html 笔记 http:/ ...

  9. MySQL自动设置create_time和update_time

    参考表结构 CREATE TABLE `t_baby` ( `baby_id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, ...

  10. OO第三阶段总结

    软件形式化方法历史 形式化方法的研究高潮始于20世纪60年代后期,针对当时所谓"软件危机",人们提出种种解决方法,归纳起来有两类:一是采用工程方法来组织.管理软件的开发过程:二是深 ...