#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. codeforces Good Bye 2015 B. New Year and Old Property

    题目链接:http://codeforces.com/problemset/problem/611/B 题目意思:就是在 [a, b] 这个范围内(1 ≤ a ≤ b ≤ 10^18)统计出符合二进制 ...

  2. 【leetcode】 Palindrome Partitioniong (middle) (*^__^*)

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

  3. 【hihoCoder】第20周 线段树

    题目: 输入 每个测试点(输入文件)有且仅有一组测试数据. 每组测试数据的第1行为一个整数N,意义如前文所述. 每组测试数据的第2行为N个整数,分别描述每种商品的重量,其中第i个整数表示标号为i的商品 ...

  4. NEFU 1112 粉刷栅栏算法

    题目链接 中文题 简单搜索题 例数据 输入 6 1 1 1 1 9 9 输出 3 注意是每一个递归搜索都返回一个min 而不是只有总的返回min #include <cstdio> #in ...

  5. HDU 1159 Common Subsequence --- DP入门之最长公共子序列

    题目链接 基础的最长公共子序列 #include <bits/stdc++.h> using namespace std; ; char c[maxn],d[maxn]; int dp[m ...

  6. IOS - 消息推送原理和实现

    一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1.Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Pr ...

  7. vs win32 & MFC 指针默认位置

    一开始win32指针所在的位置是与debug文件夹同级的.即打开打开改程序的第一个文件夹这一级. MFC指针是在第二个debug下头,就是打开第二个project名词的文件夹下头,e.g., &quo ...

  8. 求sqrt()底层效率问题(二分/牛顿迭代)

    偶然看见一段求根的神代码,于是就有了这篇博客: 对于求根问题,通常我们可以调用sqrt库函数,不过知其然需知其所以然,我们看一下求根的方法: 比较简单方法就是二分咯: 代码: #include< ...

  9. hdu 2087剪花布条

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 思路:正常KMP求解aaaaaa  aa得到的结果是6,这题是3.仅仅改一点代码就行 当匹配完之 ...

  10. route netstat -rn

    -n :不要使用通讯协定或主机名称,直接使用ip或port number; -ee:使用更详细的资讯来显示 [root@NB data]# route -nee Kernel IP routing t ...