#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代码的更多相关文章

  1. Splay代码简化版

    皆さん.こんにちは.上一篇文章,我们讲了Splay如何实现.这一篇我们来让我们的伸展树短一点. 上一篇Splay讲解的链接:リンク. 首先还是变量的定义,在这里呢,我把一些小函数也用Define来实现 ...

  2. 普通平衡树与文艺平衡树的splay代码

    主要综合借鉴了yyb和马前卒两位大佬的. //普通平衡树 #include <cstdio> #include <cctype> #include <cstring> ...

  3. 将近半个小时,把一小段简短的汇编代码写成了C语言代码

    我自己看,感觉好像一句一句翻译的,写得很是生硬,不如书上写的灵活 0040137E    8B7424 04       MOV ESI,DWORD PTR SS:[ESP+4]00401382    ...

  4. 一个 11 行 Python 代码实现的神经网络

    一个 11 行 Python 代码实现的神经网络 2015/12/02 · 实践项目 · 15 评论· 神经网络 分享到:18 本文由 伯乐在线 - 耶鲁怕冷 翻译,Namco 校稿.未经许可,禁止转 ...

  5. [C#] 用一种更优美的方式来替换掉又多又长的switch-case代码段

    switch-case语句是我们编码过程中常用的一种分支语句.然而正所谓成也萧何败萧何,每当我们向一个已经拥有了成百上千行的switch-case代码段中添加新的case分支的时候,我们是否有过为代码 ...

  6. 如何把if-else代码重构成高质量代码

    原文:https://blog.csdn.net/qq_35440678/article/details/77939999 本文提纲: 为什么我们写的代码都是if-else? 这样的代码有什么缺点? ...

  7. 算法笔记--Splay && Link-Cut-Tree

    Splay 参考:https://tiger0132.blog.luogu.org/slay-notes 普通模板: ; ], val[N], cnt[N], fa[N], sz[N], lazy[N ...

  8. PHP 代码规范、流程规范、git规范

    1. 命名规范 (1).变量命名规范 1.变量使用驼峰命名法 禁止使用拼音或者拼音加数字 2.变量也应具有描述性,杜绝一切拼音.或拼音英文混杂的命名方式 3.变量包数字.字母和下划线字符,不允许使用其 ...

  9. 【Luogu】P1486郁闷的出纳员(Splay)

    题目链接 名副其实的调了一下午…… 每做一道题都是对我那不规范的Splay代码的刀刻斧凿一般的修正啊…… Splay.如果有一批员工不干了,那就找还能干的薪水最少的员工,把它splay到根,删除它的左 ...

随机推荐

  1. Effective C++ -----条款05:了解C++默默编写并调用哪些函数

    面对“内含reference成员或者含const成员”的class内支持赋值操作,你必须自己定义copy assignment操作符. 如果某个base classes将copy assignment ...

  2. 迭代器iterator

    现在接着上篇的,写一来标识vector 的元素的对象迭代器iterator: 还是通过具体代码举例: 下面我讲了一个我暑期团队的故事哦~~: #include<iostream> #inc ...

  3. 创建URL为空的解决办法

    在使用+URLWithString:或-initWithString:创建一个URL对象时,提供的参数字符串必须符合RFC 2396标准(O网页链接.而这两个方法又是根据RFC 1738(O网页链接和 ...

  4. 虚拟机中的centos在nat模式下连不上外网

    这两天需要配置ftp服务器,可是虚拟机在nat模式下死活连不上外网,主机能够通过该ssh与虚拟机进行连接,虚拟机也能ping同一网段主机的IP地址,但就是ping不通外网, 开始我是这样配置的: 主机 ...

  5. CSS实现限制显示的字数,超出显示"..."

    一.背景 在实际项目中,我们常常需要对某些页面的某些特定区域显示指定数量的内容,超出的内容显示"..."来进行美化页面,那么应该怎么做呢?今天就让我们来看看如何达到这一效果. 二. ...

  6. 25个增强iOS应用程序性能的提示和技巧(中级篇)(3)

    25个增强iOS应用程序性能的提示和技巧(中级篇)(3) 2013-04-16 14:42 破船之家 beyondvincent 字号:T | T 本文收集了25个关于可以提升程序性能的提示和技巧,分 ...

  7. jsDoc的使用

    nodeJS使用: 直接:npm install jsdoc -g使用:jsdoc [name].js 简介 JsDoc Toolkit 是一款辅助工具,你只需要根据约定在 JavaScript 代码 ...

  8. python 获取启动参数

    pytho软件编写过程中,会经常使用带参数的启动脚本,这里记载下如何获取输入的参数. 使用sys.argv可获取启动时输入的所有参数,这个是数组,直接使用[]就可以获取,[0]代表的是启动文件时输入的 ...

  9. .pdb文件的使用方法

    1.Demo1:用DLL_01生成my.dll.my.pdb.my.lib文件. 2.Demo2:在DLL_01_APP_02中使用DLL_01的dll. 步骤: 1.vs2008打开DLL_01_A ...

  10. Ruby on Rails 接口无法调试的问题

    1. 客户端 ip 与服务器 ip需要在同一网段 2. 如果 rails 版本是4.2及以上需要通过 rails s -b 0.0.0.0启动 3. 跑服务的mac需要关闭防火墙