splay模板整理
1.插入一个数
void insert(int x)
{
if (!root)
{
++tot;
e[tot].left = e[tot].right = e[tot].fa = ;
e[tot].v = x;
e[tot].cnt = sizee[tot] = ;
root = tot;
return;
}
int now = root,fa = ;
while ()
{
if(e[now].v == x)
{
e[now].cnt++;
update(now);
update(fa);
splay(now);
break;
}
fa = now;
if (e[now].v < x)
now = e[now].right;
else
now = e[now].left;
if (!now)
{
++tot;
e[tot].left = e[tot].right = ;
e[tot].fa = fa;
e[tot].v = x;
e[tot].cnt = sizee[tot] = ;
if (e[fa].v < x)
e[fa].right = tot;
else
e[fa].left = tot;
update(fa);
splay(tot);
break;
}
}
}
2.splay
void splay(int x,int yy)
{
if (yy == )
root = x;
while (e[x].fa != yy)
{
pushdown(x);
int y = e[x].fa;
int z = e[y].fa;
if (z == yy || z == )
{
if (x == e[y].left)
turnr(x);
else
turnl(x);
}
else
{
if (e[z].left == y && e[y].left == x)
{
turnr(y);
turnr(x);
}
else
{
if (e[z].right == y && e[y].right == x)
{
turnl(y);
turnl(x);
}
else
{
if (e[z].left == y && e[y].right == x)
{
turnl(x);
turnr(x);
}
else
{
turnr(x);
turnl(x);
}
}
}
}
}
if (yy == )
root = x;
}
3.左右旋
void turnr(int x)
{
pushdown(x);
int y = e[x].fa;
int z = e[y].fa;
e[y].left = e[x].right;
if (e[x].right != )
e[e[x].right].fa = y;
e[x].fa = z;
if (z != )
{
if (e[z].left == y)
e[z].left = x;
else
e[z].right = x;
}
e[x].right = y;
e[y].fa = x;
update(x);
update(y);
} void turnl(int x)
{
pushdown(x);
int y = e[x].fa;
int z = e[y].fa;
e[y].right = e[x].left;
if (e[x].left != )
e[e[x].left].fa = y;
e[x].fa = z;
if (z != )
{
if (e[z].left == y)
e[z].left = x;
else
e[z].right = x;
}
e[x].left = y;
e[y].fa = x;
update(x);
update(y);
}
4.找前驱/后继(若点已经在splay里面)
int findl(int x)
{
int y = e[x].left;
if (y == -)
return y;
while (e[y].right != -)
y = e[y].right;
return y;
} int findr(int x)
{
int y = e[x].right;
if (y == -)
return y;
while (e[y].left != -)
y = e[y].left;
return y;
}
若点不在splay里面
void findl(int x)
{
int now = root;
temp1 = -;
v1 = 0x7fffffff;
while (now != -)
{
if (e[now].v < x && (x - e[now].v) < v1)
{
temp1 = now;
v1 = x - e[now].v;
}
if (e[now].v < x)
now = e[now].right;
else
now = e[now].left;
}
} void findr(int x)
{
int now = root;
temp2 = -;
v2 = 0x7fffffff;
while (now != -)
{
if (e[now].v > x && (e[now].v - x) < v2)
{
temp2 = now;
v2 = e[now].v - x;
}
if (e[now].v < x)
now = e[now].right;
else
now = e[now].left;
}
}
5.删除
void del(int x)
{
int p = find(x);
splay(p);
if (e[p].cnt > )
{
e[p].cnt--;
update(p);
return;
}
if (e[p].left == - && e[p].right == -)
{
root = -;
return;
}
if (e[p].left == -)
{
root = e[p].right;
e[e[p].right].fa = -;
return;
}
if (e[p].right == -)
{
root = e[p].left;
e[e[p].left].fa = -;
return;
}
int j = e[p].left;
while (e[j].right != -)
j = e[j].right;
splay(j);
e[j].right = e[p].right;
e[e[p].right].fa = j;
update(j);
}
6.查询数x的排名
int query(int x)
{
int p = root,res = ;
while (p != -)
{
if (x < e[p].v)
p = e[p].left;
else
{
res += getsize(e[p].left);
if (x == e[p].v)
return res + ;
res += e[p].cnt;
p = e[p].right;
}
}
return res;
}
7.查询排名为x的数
int query2(int x)
{
int p = root;
while (p != -)
{
if (e[p].left && x <= sizee[e[p].left])
p = e[p].left;
else
{
int temp = getsize(e[p].left) + e[p].cnt;
if (x <= temp)
return e[p].v;
x -= temp;
p = e[p].right;
}
}
return p;
}
8.各种区间操作(bzoj1500代码):
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = ,inf = ;
stack <int> s;
int n,m,a[maxn],root,tot,sizee[maxn]; struct node
{
int fa,left,right,v,sum,ans,lmax,rmax,tag,cnt;
}e[maxn]; void pushup(int x)
{
sizee[x] = + sizee[e[x].left] + sizee[e[x].right];
e[x].sum = e[e[x].left].sum + e[e[x].right].sum + e[x].v;
e[x].lmax = max(e[e[x].left].lmax,e[e[x].left].sum + e[x].v + max(,e[e[x].right].lmax));
e[x].rmax = max(e[e[x].right].rmax,e[e[x].right].sum + e[x].v + max(,e[e[x].left].rmax));
e[x].ans = max(e[e[x].left].ans,e[e[x].right].ans);
e[x].ans = max(e[x].ans,max(e[e[x].left].rmax,) + e[x].v + max(,e[e[x].right].lmax));
} void fan(int x)
{
int t = e[x].lmax;
e[x].lmax = e[x].rmax;
e[x].rmax = t;
t = e[x].left;
e[x].left = e[x].right;
e[x].right = t;
e[x].tag ^= ;
} void cover(int x,int y)
{
e[x].sum = sizee[x] * y;
e[x].v = y;
e[x].maxx = y;
if (y <= )
e[x].lmax = e[x].rmax = e[x].ans = y;
else
e[x].lmax = e[x].rmax = e[x].ans = y * sizee[x];
e[x].cnt = ;
} void pushdown(int x)
{
if (e[x].tag)
{
if (e[x].left)
fan(e[x].left);
if (e[x].right)
fan(e[x].right);
e[x].tag = ;
}
if (e[x].cnt)
{
if (e[x].left)
cover(e[x].left,e[x].v);
if (e[x].right)
cover(e[x].right,e[x].v);
e[x].cnt = ;
}
} void build(int l,int r,int &x,int y)
{
if (l > r)
return;
if (!x)
{
if (!s.empty())
{
x = s.top();
s.pop();
}
else
x = ++tot;
}
int mid = (l + r) >> ;
e[x].v = a[mid];
e[x].fa = y;
build(l,mid - ,e[x].left,x);
build(mid + ,r,e[x].right,x);
pushup(x);
} void turnr(int x)
{
pushdown(x);
int y = e[x].fa;
int z = e[y].fa;
e[y].left = e[x].right;
if (e[x].right != )
e[e[x].right].fa = y;
e[x].fa = z;
if (z != )
{
if (e[z].left == y)
e[z].left = x;
else
e[z].right = x;
}
e[x].right = y;
e[y].fa = x;
pushup(x);
pushup(y);
} void turnl(int x)
{
pushdown(x);
int y = e[x].fa;
int z = e[y].fa;
e[y].right = e[x].left;
if (e[x].left != )
e[e[x].left].fa = y;
e[x].fa = z;
if (z != )
{
if (e[z].left == y)
e[z].left = x;
else
e[z].right = x;
}
e[x].left = y;
e[y].fa = x;
pushup(x);
pushup(y);
} void splay(int x,int yy)
{
while (e[x].fa != yy)
{
pushdown(x);
int y = e[x].fa;
int z = e[y].fa;
if (z == || z == yy)
{
if (e[y].left == x)
turnr(x);
else
turnl(x);
}
else
{
if (e[z].left == y && e[y].left == x)
{
turnr(y);
turnr(x);
}
else
{
if (e[z].right == y && e[y].right == x)
{
turnl(y);
turnl(x);
}
else
{
if (e[z].left == y && e[y].right == x)
{
turnl(x);
turnr(x);
}
else
{
turnr(x);
turnl(x);
}
}
}
}
}
if (yy == )
root = x;
pushup(x);
} int find(int x,int k)
{
pushdown(x);
if (k > sizee[e[x].left] + )
return find(e[x].right,k - - sizee[e[x].left]);
if (k == sizee[e[x].left] + )
return x;
return find(e[x].left,k);
} void del(int x)
{
if (!x)
return;
s.push(x);
del(e[x].left);
del(e[x].right);
sizee[x] = e[x].left = e[x].right = e[x].cnt = e[x].tag = e[x].fa = e[x].sum = e[x].v = ;
e[x].maxx = e[x].lmax = e[x].rmax = e[x].ans = -inf;
} int main()
{
for (int i = ; i < maxn; i++)
e[i].lmax = e[i].rmax = e[i].ans = -inf;
scanf("%d%d",&n,&m);
for (int i = ; i <= n; i++)
scanf("%d",&a[i]);
build(,n + ,root,);
root = ;
for (int i = ; i <= m; i++)
{
char s[];
scanf("%s",s);
if (s[] == 'I')
{
int x,y;
scanf("%d%d",&x,&y);
for (int j = ; j <= y; j++)
scanf("%d",&a[j]);
int p = find(root,x + ),q = find(root,x + );
splay(p,);
splay(q,p);
build(,y,e[q].left,q);
pushup(q);
pushup(p);
}
if (s[] == 'D')
{
int x,y;
scanf("%d%d",&x,&y);
int p = find(root,x),q = find(root,x + y + );
splay(p,);
splay(q,p);
del(e[q].left);
e[q].left = ;
pushup(q);
pushup(p);
}
if (s[] == 'M' && s[] == 'K')
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
int p = find(root,x),q = find(root,x + y + );
splay(p,);
splay(q,p);
cover(e[q].left,z);
pushup(q);
pushup(p);
}
if (s[] == 'R')
{
int x,y;
scanf("%d%d",&x,&y);
int p = find(root,x),q = find(root,x + y + );
splay(p,);
splay(q,p);
if (e[q].left && !e[e[q].left].tag)
fan(e[q].left);
pushup(q);
pushup(p);
}
if (s[] == 'G')
{
int x,y;
scanf("%d%d",&x,&y);
int p = find(root,x),q = find(root,x + y + );
splay(p,);
splay(q,p);
printf("%d\n",e[e[q].left].sum);
}
if (s[] == 'M' && s[] == 'X')
{
int p = find(root,),q = find(root,sizee[root]);
splay(p,);
splay(q,p);
printf("%d\n",e[e[q].left].ans);
}
} return ;
}
splay模板整理的更多相关文章
- [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)
解题关键:splay模板题整理. 如何不加入极大极小值?(待思考) #include<cstdio> #include<cstring> #include<algorit ...
- ACM算法模板整理
史诗级ACM模板整理 基本语法 字符串函数 istream& getline (char* s, streamsize n ); istream& getline (char* s, ...
- bzoj 1588 splay模板题
用晚自习学了一下splay模板,没想象中那么难,主要是左旋和右旋可以简化到一个函数里边,减少代码长度... #include<iostream> #include<cstdio> ...
- COJ 1002 WZJ的数据结构(二)(splay模板)
我的LCC,LCT,Splay格式终于统一起来了... 另外..这个形式的Splay是标准的Splay(怎么鉴别呢?看Splay函数是否只传了一个变量node就行),刘汝佳小白书的Splay写的真是不 ...
- Splay 模板
Splay 模板 struct SplayTree{ const static int maxn = 1e5 + 15; int ch[maxn][2] , key[maxn] , s[maxn] , ...
- BZOJ1588 [HNOI2002]营业额统计 splay模板
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 16189 Solved: 6482 [Submit][S ...
- 文艺平衡树(splay模板)
题干:splay模板,要求维护区间反转. splay是一种码量小于treap,但支持排名,前驱后继等treap可求的东西,也支持区间反转的平衡树. 但是有两个坏处: 1.splay常数远远大于trea ...
- 字符串系列——KMP模板整理
KMP模板整理 KMP与扩展KMP: /*vs 2017/ vs code以外编译器,去掉windows.h头文件和system("pause");*/ #include<i ...
- [洛谷P3391] 文艺平衡树 (Splay模板)
初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...
随机推荐
- Java构造方法经典例题
1.在程序中,经常要对时间进行操作,但是并没有时间类型的数据.那么,我们可以自己实现一个时间类,来满足程序中的需要. 定义名为MyTime的类,其中应有三个整型成员:时(hour),分(minute) ...
- 软件杯python-flask遇到的坑有感!
大三下,对于我考研的人来说,时间不要太紧张,参加软件杯也是系主任要求,题目是公共地点人流量的检测,个人还是个菜鸟,但是把遇到的一些大家可能不小心会出现的问题贴出来,困扰我很久,还没睡好觉!!! Que ...
- vue2.0中ckeckbox(复选框)的使用心得,及对click事件和change的理解
最近在公司项目中使用vue2.0做开发,在使用checkbox时遇到了一些问题,首先我们先了解一下需求. 如上如所示,在上方复选框被点击时,更改下方p标签的文本内容为:复选框已被选中.并将p标签文字颜 ...
- iView - Form中想要重置DatePicker生效,必须给DatePicker绑定value属性
Form中想要重置DatePicker生效,必须给DatePicker绑定value属性
- HashMap 排序
本文章,摘抄自:2018黑马程序最新面试题汇总 已知一个 HashMap<Integer,User>集合, User 有 name(String)和 age(int)属性.请写一个方法实现 ...
- pip3 的安装 同时安装lxml和pygame
ubuntu18.04中 首先查看自己电脑的python版本,一般都会有2, 和3 python -V python3 -V 查看pip版本 pip -V pip3 -V 现在我们就可以开始安装我们的 ...
- LED室内定位算法:RSS,TOA,AOA,TDOA(转载)
转载自:https://blog.csdn.net/baidu_38197452/article/details/77115935 基于LED的室内定位算法大致可以分为四类: 1. 几何测量法 这种方 ...
- linux下的source命令
Linux Source命令及脚本的执行方式解析 当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile ...
- sql中一个服务器建立另一个服务器的连接
EXEC sp_addlinkedserver 'TonyLink','','SQLOLEDB','111.111.1.111(服务器名)' EXEC sp_addlinkedsrvlogin 'To ...
- vue时时监听input输入框中 输入内容 写法
Vue input 监听 使用 v-on:input="change" 实现即可 App.vue <template> <div> <md-field ...