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

/*
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. bash变量详解

    bash变量详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 大家都知道Shell是一门脚本语言,脚本语言的最好的优点就是我们写的代码不需要编辑就可以直接运行,当然你也可以把它归 ...

  2. python---ORM之SQLAlchemy(4)relationship多对多练习

    练习一:朋友 import sqlalchemy from sqlalchemy import create_engine from sqlalchemy import Column, String, ...

  3. vue基础篇---生命周期

    每个钩子函数都在啥时间触发 beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用. created 实例已经创建完成之 ...

  4. tomcat中配置servlet.xml的JNDI或JDBC连接数据库【原】

    tomcat中配置servlet.xml的JNDI或JDBC连接数据库 一. JNDI 1. tomcat环境 找到X:\xxx\......\apache-tomcat-6.0.39\conf\se ...

  5. VS2013中修改MFC对话框左上角和exe图标

    一.开发环境 1.VS2013: 2.C++ / MFC: 二.更改步骤 1)创建一个新工程,可以什么都不加.打开“资源视图”, 右键点击项目名称,选择“添加资源”,导入“Icon”资源文件(事先准备 ...

  6. .NET 单点登录开源项目

    1. https://www.apereo.org/cas/client-integration 2.源码下载 https://wiki.jasig.org/display/CASC/.Net+Cas ...

  7. C# ffmpeg工具将视频转为SWF格式

    1.下载ffmpeg工具 using System; using System.Collections; using System.Configuration; using System.Data; ...

  8. C# 摇奖机实例(线程)

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. JavaScript之DOM概念

    一.DOM概念 1.DOM是什么? 1.1 起源.DOM起源于Netscape与Microsoft 公司的DHTML(动态HTML). 1.2 名词解释.Document Object Model,文 ...

  10. 【学习博客】Python学习初体验

    本周是正式开始学习Python的第一周.很久不写代码了,毕业第5年了,期间几乎没怎么动过手.这段时间比较规律.密集的学习又让我找回了当时的感觉,还不算陌生,我挺喜欢的这种能实实在在看到自己知识增长的状 ...