支持区间操作。

  单点操作和区间操作分开使用,需要一起使用需要部分修改。

  对应题目FJUTOJ2490

 #include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int N=,INF=0x3f3f3f3f; struct Splay_Tree
{
struct Node
{
int val,Max,add,Size,son[];
bool rev;
void init(int _val)
{
val=Max=_val,Size=;
add=rev=son[]=son[]=;
}
} T[N];
int fa[N],root,tot; void pushDown(int x)
{
if(x==)return ;
if(T[x].add)
{
if(T[x].son[])
{
T[T[x].son[]].val+=T[x].add;
T[T[x].son[]].Max+=T[x].add;
T[T[x].son[]].add+=T[x].add;
}
if(T[x].son[])
{
T[T[x].son[]].val+=T[x].add;
T[T[x].son[]].Max+=T[x].add;
T[T[x].son[]].add+=T[x].add;
}
T[x].add=;
}
if(T[x].rev)
{
if(T[x].son[])T[T[x].son[]].rev^=;
if(T[x].son[])T[T[x].son[]].rev^=;
swap(T[x].son[],T[x].son[]);
T[x].rev=;
}
} void pushUp(int x)
{
T[x].Max=T[x].val,T[x].Size=;
if(T[x].son[])
{
T[x].Max=max(T[x].Max,T[T[x].son[]].Max);
T[x].Size+=T[T[x].son[]].Size;
}
if(T[x].son[])
{
T[x].Max=max(T[x].Max,T[T[x].son[]].Max);
T[x].Size+=T[T[x].son[]].Size;
}
} void Rotate(int x,int kind)
{
int y=fa[x],z=fa[y];
T[y].son[!kind]=T[x].son[kind],fa[T[x].son[kind]]=y;
T[x].son[kind]=y,fa[y]=x;
T[z].son[T[z].son[]==y]=x,fa[x]=z;
pushUp(y);
} void Splay(int x,int goal)
{
if(x==goal)return ;
while(fa[x]!=goal)
{
int y=fa[x],z=fa[y];
pushDown(z),pushDown(y),pushDown(x);
int rx=T[y].son[]==x,ry=T[z].son[]==y;
if(z==goal)Rotate(x,rx);
else
{
if(rx==ry)Rotate(y,ry);
else Rotate(x,rx);
Rotate(x,ry);
}
}
pushUp(x);
if(goal==)root=x;
} int Select(int pos)
{
int u=root;
pushDown(u);
while(T[T[u].son[]].Size!=pos)
{
if(pos<T[T[u].son[]].Size)u=T[u].son[];
else
{
pos-=T[T[u].son[]].Size+;
u=T[u].son[];
}
pushDown(u);
}
return u;
} void update(int L,int R,int val)
{
int u=Select(L-),v=Select(R+);
Splay(u,);
Splay(v,u);
T[T[v].son[]].Max+=val;
T[T[v].son[]].val+=val;
T[T[v].son[]].add+=val;
} void Reverse(int L,int R)
{
int u=Select(L-),v=Select(R+);
Splay(u,);
Splay(v,u);
T[T[v].son[]].rev^=;
} int query(int L,int R)
{
int u=Select(L-),v=Select(R+);
Splay(u,);
Splay(v,u);
return T[T[v].son[]].Max;
} int build(int L,int R)
{
if(L>R)return ;
if(L==R)return L;
int mid=(L+R)>>,sL,sR;
T[mid].son[]=sL=build(L,mid-);
T[mid].son[]=sR=build(mid+,R);
fa[sL]=fa[sR]=mid;
pushUp(mid);
return mid;
} void init(int n)
{
T[].init(-INF),T[].init(-INF),T[n+].init(-INF);
for(int i=;i<=n+;i++)T[i].init();
root=build(,n+),fa[root]=;
fa[]=,T[].son[]=root,T[].Size=;
} inline void up(int x)
{
T[x].Size=;
if(T[x].son[])
T[x].Size+=T[T[x].son[]].Size;
if(T[x].son[])
T[x].Size+=T[T[x].son[]].Size;
} void Insert(int &t,int val,int par=)
{
if(t==)
{
t=++tot;
T[t].init(val);
fa[t]=par;
Splay(tot,);
}
else
{
int cur=t;
if(val<T[t].val)Insert(T[t].son[],val,cur);
//else if(val==T[t].val)return ;
else Insert(T[t].son[],val,cur);
up(cur);
}
} int find(int t,int v)
{
if(t==)return ;
else if(T[t].val==v)
{
Splay(t,);
return t;
}
else if(v<T[t].val)return find(T[t].son[],v);
else return find(T[t].son[],v);
} ///Delete Root
void Delete()
{
if(!T[root].son[])
{
fa[T[root].son[]]=;
root=T[root].son[];
}
else
{
int cur=T[root].son[];
while(T[cur].son[])cur=T[cur].son[];
Splay(cur,root);
T[cur].son[]=T[root].son[];
root=cur,fa[cur]=,fa[T[root].son[]]=root;
up(root);
}
} int size()
{
return T[root].Size;
} ///找前驱
int pred(int t,int v)
{
if(t==)return v;
else
{
if(v<=T[t].val)return pred(T[t].son[],v);
else
{
int ans=pred(T[t].son[],v);
if(ans==v)
ans=T[t].val,Splay(t,);
return ans;
}
}
} ///找后继
int succ(int t,int v)
{
if(t==)return v;
else
{
if(v>=T[t].val)return succ(T[t].son[],v);
else
{
int ans=succ(T[t].son[],v);
if(ans==v)
ans=T[t].val,Splay(t,);
return ans;
}
}
} void Preorder( int t ){
if( !t ) return;
Preorder( T[t].son[] );
printf("%d " , T[t].val );
Preorder( T[t].son[] );
} void init()
{
T[].init(-INF);
tot=root=;
} }; Splay_Tree tree; int main()
{
int n,ans=;
scanf("%d",&n);
tree.init();
tree.Insert(tree.root,-INF);
tree.Insert(tree.root,INF);
scanf("%d",&ans);
tree.Insert(tree.root,ans);
for(int i=,x;i<n;i++)
{
scanf("%d",&x);
if(!tree.find(tree.root,x))
{
tree.Insert(tree.root,x);
ans+=min(x-tree.pred(tree.root,x),tree.succ(tree.root,x)-x);
}
}
printf("%d\n",ans);
return ;
}

再贴一个比较麻烦的题的代码FJUT2491

 #include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int N=,INF=0x3f3f3f3f; struct Splay_Tree
{
struct Node
{
int val,Max,add,Size,son[];
bool rev;
void init(int _val)
{
val=Max=_val,Size=;
add=rev=son[]=son[]=;
}
} T[N];
int fa[N],root,tot,loc[N]; /*void pushDown(int x)
{
if(x==0)return ;
if(T[x].add)
{
if(T[x].son[0])
{
T[T[x].son[0]].val+=T[x].add;
T[T[x].son[0]].Max+=T[x].add;
T[T[x].son[0]].add+=T[x].add;
}
if(T[x].son[1])
{
T[T[x].son[1]].val+=T[x].add;
T[T[x].son[1]].Max+=T[x].add;
T[T[x].son[1]].add+=T[x].add;
}
T[x].add=0;
}
if(T[x].rev)
{
if(T[x].son[0])T[T[x].son[0]].rev^=1;
if(T[x].son[1])T[T[x].son[1]].rev^=1;
swap(T[x].son[0],T[x].son[1]);
T[x].rev=0;
}
}*/ /*void pushUp(int x)
{
T[x].Max=T[x].val,T[x].Size=1;
if(T[x].son[0])
{
T[x].Max=max(T[x].Max,T[T[x].son[0]].Max);
T[x].Size+=T[T[x].son[0]].Size;
}
if(T[x].son[1])
{
T[x].Max=max(T[x].Max,T[T[x].son[1]].Max);
T[x].Size+=T[T[x].son[1]].Size;
}
}*/ inline void up(int x)
{
T[x].Size=;
if(T[x].son[])
T[x].Size+=T[T[x].son[]].Size;
if(T[x].son[])
T[x].Size+=T[T[x].son[]].Size;
} void Rotate(int x,int kind)
{
int y=fa[x],z=fa[y];
T[y].son[!kind]=T[x].son[kind],fa[T[x].son[kind]]=y;
T[x].son[kind]=y,fa[y]=x;
T[z].son[T[z].son[]==y]=x,fa[x]=z;
up(y);
} void Splay(int x,int goal)
{
if(x==goal)return ;
while(fa[x]!=goal)
{
int y=fa[x],z=fa[y];
int rx=T[y].son[]==x,ry=T[z].son[]==y;
if(z==goal)Rotate(x,rx);
else
{
if(rx==ry)Rotate(y,ry);
else Rotate(x,rx);
Rotate(x,ry);
}
}
up(x);
if(goal==)root=x;
} int Select(int pos)
{
pos--;
int u=root;
while(T[T[u].son[]].Size!=pos)
{
if(pos<T[T[u].son[]].Size)u=T[u].son[];
else
{
pos-=T[T[u].son[]].Size+;
u=T[u].son[];
}
}
return u;
} void update(int L,int R,int val)
{
int u=Select(L-),v=Select(R+);
Splay(u,);
Splay(v,u);
T[T[v].son[]].Max+=val;
T[T[v].son[]].val+=val;
T[T[v].son[]].add+=val;
} void Reverse(int L,int R)
{
int u=Select(L-),v=Select(R+);
Splay(u,);
Splay(v,u);
T[T[v].son[]].rev^=;
} int query(int L,int R)
{
int u=Select(L-),v=Select(R+);
Splay(u,);
Splay(v,u);
return T[T[v].son[]].Max;
} int build(int L,int R)
{
if(L>R)return ;
if(L==R)return L;
int mid=(L+R)>>,sL,sR;
T[mid].son[]=sL=build(L,mid-);
T[mid].son[]=sR=build(mid+,R);
fa[sL]=fa[sR]=mid;
up(mid);
return mid;
} void init(int n)
{
T[].init(-INF);
for(int i=,x;i<=n;i++)
{
scanf("%d",&x);
T[i].init(x),loc[x]=i;
}
root=build(,n),fa[root]=;
fa[]=,T[].son[]=root,T[].Size=;
} void Insert(int &t,int val,int par=)
{
if(t==)
{
t=++tot;
T[t].init(val);
fa[t]=par;
Splay(tot,);
}
else
{
int cur=t;
if(val<T[t].val)Insert(T[t].son[],val,cur);
//else if(val==T[t].val)return ;
else Insert(T[t].son[],val,cur);
up(cur);
}
} int find(int t,int v)
{
if(t==)return ;
else if(T[t].val==v)
{
Splay(t,);
return t;
}
else if(v<T[t].val)return find(T[t].son[],v);
else return find(T[t].son[],v);
} ///Delete Root
void Delete()
{
if(!T[root].son[])
{
fa[T[root].son[]]=;
root=T[root].son[];
}
else
{
int cur=T[root].son[];
while(T[cur].son[])cur=T[cur].son[];
Splay(cur,root);
T[cur].son[]=T[root].son[];
root=cur,fa[cur]=,fa[T[root].son[]]=root;
up(root);
}
} int size()
{
return T[root].Size;
} ///找前驱
int pred(int t,int v)
{
if(t==)return v;
else
{
if(v<=T[t].val)return pred(T[t].son[],v);
else
{
int ans=pred(T[t].son[],v);
if(ans==v)
ans=T[t].val,Splay(t,);
return ans;
}
}
} int pred(int t)
{
Splay(t,);
int u=T[t].son[];
if(u==)return fa[t];
while(T[u].son[])u=T[u].son[];
return u;
} ///找后继
int succ(int t,int v)
{
if(t==)return v;
else
{
if(v>=T[t].val)return succ(T[t].son[],v);
else
{
int ans=succ(T[t].son[],v);
if(ans==v)
ans=T[t].val,Splay(t,);
return ans;
}
}
} int succ(int t)
{
Splay(t,);
int u=T[t].son[];
if(u==)return fa[t];
while(T[u].son[])u=T[u].son[];
return u;
} void Preorder( int t ){
if( !t ) return;
Preorder( T[t].son[] );
if(T[t].son[]&&fa[T[t].son[]]!=t)
printf("!");
if(loc[T[t].val]!=t)
printf("?");
printf("%d " , T[t].val );
Preorder( T[t].son[] );
} void init()
{
T[].init(-INF);
tot=root=;
} void update(int x)
{
while(x!=)
up(x),x=fa[x];
} }; Splay_Tree tree; char s[]; int main()
{
int n,m;
scanf("%d%d",&n,&m);
tree.init(n);
int x,y,loc,locm,loch;
while(m--)
{
scanf("%s",s);
if(s[]=='T')
{
scanf("%d",&x);
loc=tree.loc[x];
locm=tree.Select();
if(locm==loc)
continue;
tree.Splay(loc,);
tree.Delete();
tree.T[locm].son[]=loc;
tree.fa[loc]=locm;
tree.T[loc].son[]=tree.T[loc].son[]=;
tree.update(loc);
}
else if(s[]=='B')
{
scanf("%d",&x);
loc=tree.loc[x];
locm=tree.Select(n);
if(locm==loc)
continue;
tree.Splay(loc,);
tree.Delete();
tree.T[locm].son[]=loc;
tree.fa[loc]=locm;
tree.T[loc].son[]=tree.T[loc].son[]=;
tree.update(loc);
}
else if(s[]=='I')
{
scanf("%d%d",&x,&y);
if(y==)
{
loc=tree.loc[x];
loch=tree.succ(loc);
swap(tree.T[loc].val,tree.T[loch].val);
swap(tree.loc[tree.T[loc].val],tree.loc[tree.T[loch].val]); }
else if(y==-)
{
loc=tree.loc[x];
loch=tree.pred(loc);
swap(tree.T[loc].val,tree.T[loch].val);
swap(tree.loc[tree.T[loc].val],tree.loc[tree.T[loch].val]);
}
}
else if(s[]=='A')
{
scanf("%d",&x);
loc=tree.loc[x];
tree.Splay(loc,);
printf("%d\n",tree.T[tree.T[loc].son[]].Size);
}
else if(s[]=='Q')
{
scanf("%d",&x);
printf("%d\n",tree.T[tree.Select(x)].val);
}
//tree.Preorder(tree.root);
//printf("\n");
}
return ;
}

平衡树(Splay)模板的更多相关文章

  1. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  2. [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)

    解题关键:splay模板题整理. 如何不加入极大极小值?(待思考) #include<cstdio> #include<cstring> #include<algorit ...

  3. bzoj3224 普通平衡树 splay模板

    题目传送门 题目大意:完成一颗splay树. 思路:模板题,学着还是很有意思的. 学习splay树:蒟蒻yyb 该题模板:汪立超 #include<bits/stdc++.h> #defi ...

  4. bzoj3224 普通平衡树(splay 模板)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 11427  Solved: 4878[Submit][St ...

  5. [bzoj3224]Tyvj 1728 普通平衡树——splay模板

    题目 你需要写一种数据结构支援以下操作. 插入元素. 删除元素. 查询元素的排名. 查询第k小的元素. 查询元素前趋. 查询元素后继. 题解 BBST裸题. 代码 #include <cstdi ...

  6. P3369 【模板】普通平衡树 (splay 模板)

    题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(排名定义为比当前数小的数的个数+1.若有多 ...

  7. 【BZOJ3224】Tyvj 1728 普通平衡树 Splay

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...

  8. 文艺平衡树(splay模板)

    题干:splay模板,要求维护区间反转. splay是一种码量小于treap,但支持排名,前驱后继等treap可求的东西,也支持区间反转的平衡树. 但是有两个坏处: 1.splay常数远远大于trea ...

  9. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

  10. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

随机推荐

  1. 表的操作(Oracle和DB2)

    asc和desc 分别表示升序和降序 select * from tablename order by id desc :根据id字段按照降序排列,从大到小 select * from tablena ...

  2. C# HelpPage 接口文档配置

    1.打开项目路径如下的类文件: 1.1.找类方法 Register 下的 config.SetDocumentationProvider 并取消注释,修改 ~/App_Data/XmlDocument ...

  3. Dubbo广播模式下报错:Can't assign requested address解决办法

    原因: 尝试使用Dubbo的multicast模式,发现一运行就报Can't assign requested address的错误,造成这种原因的主要是系统中开启了IPV6协议(比如window7) ...

  4. 终极解决方案:java.security.cert.CertificateException: Certificates does not conform to algorithm constraints

    报错信息 javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Certificates does ...

  5. 初学Python(第一课)

    今天整理一下关于Python初学者的基础知识部分的第一课,因为之前学习过C,所以过于基础的知识就不详细记录了. Python相对于C\C++来说,在语法方面已经很简单了:甚至对于JavaScript也 ...

  6. Java爬虫----有道翻译初步

    目标:http://fanyi.youdao.com/ 用爬虫实现翻译功能. 利用f12查看网页Network,可以发现 有关翻译的表单请求通过  http://fanyi.youdao.com/tr ...

  7. 集成 solr6.5.1到 tomcat7(8) 中 (解决java.lang.NoSuchMethodError问题)

    ♣下载solr安装包 ♣安装solr ♣solr应用部署到tomcat下 ♣配置web.xml ♣在tomcat7启动 ♣改为在tomcat8启动 ♣在自带的Jetty里启动 ♣建立第一个Core 安 ...

  8. 由select引发的思考

    一.前言 网络编程里一个经典的问题,selec,poll和epoll的区别?这个问题刚学习编程时就接触了,当时看了材料很不明白,许多概念和思想没有体会,现在在这个阶段,再重新回头看这个问题,有一种豁然 ...

  9. python中__name__=='__main__'的作用

      学习python语法的过程中碰到了__name__=='__main__',这里做个笔记. 作用   这段代码的作用就是让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可执行. 测试 先 ...

  10. asp.net动态网站repeater控件使用及分页操作介绍

    asp.net动态网站repeater控件使用及分页操作介绍 1.简单介绍 Repeater 控件是一个容器控件,可用于从网页的任何可用数据中创建自定义列表.Repeater 控件没有自己内置的呈现功 ...