及其简短的Splay代码
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#define inf 1000000000
using namespace std;
#define getch() getchar()
inline int F() {register int aa , bb , ch;
while(ch = getch() , (ch<''||ch>'') && ch != '-'); ch == '-' ? aa=bb= : (aa=ch-'',bb=);
while(ch = getch() , ch>=''&&ch<='') aa = aa* + ch-''; return bb ? aa : -aa;
}
const int Maxn = ;
queue<int> q;
int n , m , root , sz;
int fa[Maxn] , c[Maxn][] , mx[Maxn] , lx[Maxn] , rx[Maxn] , v[Maxn] , size[Maxn] , sum[Maxn] , a[Maxn] , id[Maxn];
bool lazy[Maxn] , rev[Maxn]; void update(int x) {
int lc = c[x][] , rc = c[x][];
sum[x] = sum[lc] + sum[rc] + v[x];
size[x] = size[lc] + size[rc] + ;
mx[x] = max(mx[lc] , mx[rc]);
mx[x] = max(mx[x] , rx[lc]+v[x]+lx[rc]);
lx[x] = max(lx[lc] , sum[lc] + v[x] + lx[rc]);
rx[x] = max(rx[rc] , sum[rc] + v[x] + rx[lc]);
} void downpush(int x) {
int lc = c[x][] , rc = c[x][];
if(lazy[x]) {
rev[x] = lazy[x] = ;
if(lc) lazy[lc] = , v[lc] = v[x] , sum[lc] = v[x]*size[lc];
if(rc) lazy[rc] = , v[rc] = v[x] , sum[rc] = v[x]*size[rc];
if(v[x] >= ) {
if(lc) lx[lc] = rx[lc] = mx[lc] = sum[lc];
if(rc) lx[rc] = rx[rc] = mx[rc] = sum[rc];
}
else {
if(lc) lx[lc] = rx[lc] = , mx[lc] = v[x];
if(rc) lx[rc] = rx[rc] = , mx[rc] = v[x];
}
}
if(rev[x]) {
rev[x] = ;
rev[lc] ^= ;
rev[rc] ^= ;
swap(lx[lc] , rx[lc]);
swap(lx[rc] , rx[rc]);
c[x][] = rc;
c[x][] = lc;
swap(lx[x] , rx[x]);
}
} void rotate(int&root , int x) {
int y = fa[x] , z = fa[y] , p , q;
if(x == c[y][]) p = ; else p = ;
q = p^;
if(y == root) root = x;
else {
if(c[z][] == y) c[z][] = x;
else c[z][] = x;
}
fa[x] = z; fa[y] = x; fa[c[x][q]] = y;
c[y][p] = c[x][q]; c[x][q] = y;
update(y); update(x);
}
void splay(int&root , int x) {
int y , z;
while(x != root) {
y = fa[x] , z = fa[y];
if(y != root) {
if((x == c[y][]) ^ (y == c[z][])) rotate(root , x);
else rotate(root , y);
}
rotate(root , x);
}
} int find(int x , int rk) {
downpush(x);
int lc = c[x][] , rc = c[x][];
if(size[lc] + == rk) return x;
if(size[lc] >= rk) return find(lc , rk);
else return find(rc , rk-size[lc]-);
} void rec(int x) {
if(!x) return ;
int lc = c[x][] , rc = c[x][];
rec(lc);rec(rc);q.push(x);
fa[x] = c[x][] = c[x][] = lazy[x] = rev[x] = ;
} int split(int k , int tot) {
int x = find(root , k);
splay(root , x);
x = find(root , k+tot+);
splay(c[root][] , x);
return c[ c[root][] ][];
} void query(int k , int tot) {
int x = split(k , tot);
printf("%d\n",sum[x]);
} void modify(int k , int tot , int val) {
int x = split(k , tot) , y = fa[x];
v[x] = val; lazy[x] = ; sum[x] = size[x]*val;
if(val >= ) lx[x] = rx[x] = mx[x] = sum[x];
else lx[x] = rx[x] = , mx[x] = val;
update(y); update(fa[y]);
} void reverse(int k , int tot) {
int x = split(k , tot);
if(!lazy[x]) {
rev[x] ^= ;
downpush(x);
update(fa[x]);
update(fa[fa[x]]);
}
} void erase(int k , int tot) {
int x = split(k , tot) , y = fa[x];
rec(x); c[y][] = ;
update(y); update(fa[y]);
}
void build(int l,int r,int f)
{
if(l>r)return;
int mid=(l+r)>>,now=id[mid],last=id[f];
if(l==r)
{
sum[now]=a[l];size[now]=;
lazy[now]=rev[now]=;
if(a[l]>=)lx[now]=rx[now]=mx[now]=a[l];
else lx[now]=rx[now]=,mx[now]=a[l];
}
else build(l,mid-,mid),build(mid+,r,mid);
v[now]=a[mid];fa[now]=last;update(now);
c[last][mid>=f]=now;
}
void insert(int k,int tot)
{
for(int i=;i<=tot;i++)a[i]=F();
for(int i=;i<=tot;i++)
if(!q.empty())id[i]=q.front(),q.pop();
else id[i]=++sz;
build(,tot,);int z=id[(+tot)>>];
int x=find(root,k+),y=find(root,k+);
splay(root,x);splay(c[x][],y);
fa[z]=y;c[y][]=z;
update(y);update(x);
} int main() {
n = F(); m = F();
mx[] = a[] = a[n+] = -inf;
for(int i=; i<=n; ++i) {
a[i+] = F();
}
for(int i=;i<=n+;i++)id[i]=i;
build(,n+,);
root = (n+) >> ;sz = n + ;
int k , tot , val;
char ch[];
while(m--) {
scanf("%s",ch);
if(ch[]!='M' || ch[] != 'X') k = F() , tot = F();
if(ch[] == 'I') insert(k , tot);
if(ch[] == 'D') erase(k , tot);
if(ch[] == 'M') {
if(ch[] == 'X') printf("%d\n",mx[root]);
else val = F() , modify(k , tot , val);
}
if(ch[] == 'R') reverse(k , tot);
if(ch[] == 'G') query(k , tot);
}
}
Splay的核心操作
void rotate(int&root , int x) {
int y = fa[x] , z = fa[y] , p , q;
if(x == c[y][]) p = ; else p = ;
q = p^;
if(y == root) root = x;
else {
if(c[z][] == y) c[z][] = x;
else c[z][] = x;
}
fa[x] = z; fa[y] = x; fa[c[x][q]] = y;
c[y][p] = c[x][q]; c[x][q] = y;
update(y); update(x);
}
void splay(int&root , int x) {
int y , z;
while(x != root) {
y = fa[x] , z = fa[y];
if(y != root) {
if((x == c[y][]) ^ (y == c[z][])) rotate(root , x);
else rotate(root , y);
}
rotate(root , x);
}
}
及其简短的Splay代码的更多相关文章
- Splay代码简化版
皆さん.こんにちは.上一篇文章,我们讲了Splay如何实现.这一篇我们来让我们的伸展树短一点. 上一篇Splay讲解的链接:リンク. 首先还是变量的定义,在这里呢,我把一些小函数也用Define来实现 ...
- 普通平衡树与文艺平衡树的splay代码
主要综合借鉴了yyb和马前卒两位大佬的. //普通平衡树 #include <cstdio> #include <cctype> #include <cstring> ...
- 将近半个小时,把一小段简短的汇编代码写成了C语言代码
我自己看,感觉好像一句一句翻译的,写得很是生硬,不如书上写的灵活 0040137E 8B7424 04 MOV ESI,DWORD PTR SS:[ESP+4]00401382 ...
- 一个 11 行 Python 代码实现的神经网络
一个 11 行 Python 代码实现的神经网络 2015/12/02 · 实践项目 · 15 评论· 神经网络 分享到:18 本文由 伯乐在线 - 耶鲁怕冷 翻译,Namco 校稿.未经许可,禁止转 ...
- [C#] 用一种更优美的方式来替换掉又多又长的switch-case代码段
switch-case语句是我们编码过程中常用的一种分支语句.然而正所谓成也萧何败萧何,每当我们向一个已经拥有了成百上千行的switch-case代码段中添加新的case分支的时候,我们是否有过为代码 ...
- 如何把if-else代码重构成高质量代码
原文:https://blog.csdn.net/qq_35440678/article/details/77939999 本文提纲: 为什么我们写的代码都是if-else? 这样的代码有什么缺点? ...
- 算法笔记--Splay && Link-Cut-Tree
Splay 参考:https://tiger0132.blog.luogu.org/slay-notes 普通模板: ; ], val[N], cnt[N], fa[N], sz[N], lazy[N ...
- PHP 代码规范、流程规范、git规范
1. 命名规范 (1).变量命名规范 1.变量使用驼峰命名法 禁止使用拼音或者拼音加数字 2.变量也应具有描述性,杜绝一切拼音.或拼音英文混杂的命名方式 3.变量包数字.字母和下划线字符,不允许使用其 ...
- 【Luogu】P1486郁闷的出纳员(Splay)
题目链接 名副其实的调了一下午…… 每做一道题都是对我那不规范的Splay代码的刀刻斧凿一般的修正啊…… Splay.如果有一批员工不干了,那就找还能干的薪水最少的员工,把它splay到根,删除它的左 ...
随机推荐
- Java多线程Socket在控制台输出的多人聊天室编程
服务器端代码 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java ...
- ios 中的autoresizingMask
以前对这个知识理解的不太对,看了下面这个地址的文章后,感觉说的对,也没检验,今天实验后,发现是错的...在这里对以前读过此文的朋友表示抱歉. 原文地址如下: http://www.cnblogs.co ...
- MySQL字符集转换引发插入乱码问题
根据http://www.cnblogs.com/cchust/p/4601536.html进行验证测试 问题背景 在mysql上面执行一条普通的insert语句,结果报错: Incorrect st ...
- 迷宫问题_BFS_挑战程序设计竞赛p34
给定一个N*M的迷宫,求从起点到终点的最小步数. N,M<100: 输入: 10 10#S######.#......#..#.#.##.##.#.#........##.##.####.... ...
- VB中字符串操作函数
Len Len(string|varname) 返回字符串内字符的数目,或是存储一变量所需的字节数. Trim Trim(string) 将字符串前后的空格去掉 Ltrim Ltrim(string) ...
- 【xml】利用OpenCV解析
看到一篇讲的很清楚的博客:http://blog.csdn.net/jarvischu/article/details/8481510
- HDU 4387 Stone Game (博弈)
题目:传送门. 题意:长度为N的格子,Alice和Bob各占了最左边以及最右边K个格子,每回合每人可以选择一个棋子往对面最近的一个空格移动.最先不能移动的人获得胜利. 题解: k=1时 很容易看出,n ...
- SQL常用命令整理
1.增加字段 alter table docdsp add dspcodechar(200)2.删除字段 ALTER TABLE table_NAME DROP COLUMNcolum ...
- ODBC连接发生错误:未发现数据源名称并且未指定默认驱动程序
程序在使用ODBC方式连接数据库时发生错误: ERROR [IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序. 什么原因造成的呢? 本人使用&l ...
- springMVC创建基础变量
在springMVC中有一些变量是基础变量,可以在全局多个地方使用,在修改规则的时候,这样只用修改一个地方就好了,而且可以避免很多不必要的bug出现下面就来总结一下在我的项目中如何去创建一个全局基础变 ...