支持区间操作。

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

  对应题目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. idea出现Error:Maven Resources Compiler: Maven project configuration required for module 'market' isn't available.

    idea出现如下错误解决办法 1.重新在Build-Rebuild project 既可以解决啦

  2. JS标签的各种事件的举例

    1.鼠标单击事件( onclick ) <!DOCTYPE HTML> <html> <head> <meta http-equiv="Conten ...

  3. SpringBoot中关于Mybatis使用的三个问题

    SpringBoot中关于Mybatis使用的三个问题 转载请注明源地址:http://www.cnblogs.com/funnyzpc/p/8495453.html 原本是要讲讲PostgreSQL ...

  4. HDU - 2154 线性dp

    思路:0表示A,1表示B,2表示C,d(i, j)表示在第j次时正好到达i. AC代码 #include <cstdio> #include <cmath> #include ...

  5. hdu1425 哈希技术

    常用的技巧,把每个数字分别对应数组的下标,如果存在小于零的数字,就统一加一个数使得都能映射到一个下标上去. AC代码: #include<cstdio> #include<cstri ...

  6. MacOS下SVN迁移Git踩坑记

    1. First Blood 之前在Windows环境下进行svn到git的迁移是很简单的,(参考官方文档:https://git-scm.com/book/zh/v1/Git-%E4%B8%8E%E ...

  7. Java 多线程入门

    进程与线程 在学习Java多线程之前,先简单复习一下进程与线程的知识. 进程:进程是系统进行资源分配和调度的基本单位,可以将进程理解为一个正在执行的程序,比如一款游戏. 线程:线程是程序执行的最小单位 ...

  8. Wireshark理解TCP乱序重组和HTTP解析渲染

    TCP数据传输过程 TCP乱序重组原理 HTTP解析渲染 TCP乱序重组 TCP具有乱序重组的功能.(1)TCP具有缓冲区(2)TCP报文具有序列号所以,对于你说的问题,一种常见的处理方式是:TCP会 ...

  9. 普通权限拿webshell

    普通权限拿webshell:   1.0day拿webshell:这个不多说.可以去网上搜索一些, 比如你找到你搞的网站cms是discz的,你可以搜索一些相 关0day直接拿   2.修改网站上传类 ...

  10. Java中的Lock与synchronized

    并发编程学习笔记之Lock与synchronized 一.什么是可重入锁 Lcok在Java中是一个接口,一般在面试问题中问到的可能是ReentrantLock与synchronized的区别.Ree ...