这东西都没什么板子着实让我很难受啊,只能到网上抄抄补补,

  记下两个用到的博客

https://blog.csdn.net/clove_unique/article/details/50630280

https://blog.csdn.net/ophunter_lcm/article/details/18157185

  BZOJ 3224

  复制粘贴?...

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <algorithm>
#include <time.h> #define SIGMA_SIZE 26
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) (x&-x)
#define foe(i, a, b) for(int i=a; i<=b; i++)
#define fo(i, a, b) for(int i=a; i<b; i++);
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL;
inline LL LMax(LL a, LL b) { return a>b ? a : b; }
inline LL LMin(LL a, LL b) { return a>b ? b : a; }
inline LL lgcd(LL a, LL b) { return b == ? a : lgcd(b, a%b); }
inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; } //a*b = gcd*lcm
inline int Max(int a, int b) { return a>b ? a : b; }
inline int Min(int a, int b) { return a>b ? b : a; }
inline int gcd(int a, int b) { return b == ? a : gcd(b, a%b); }
inline int lcm(int a, int b) { return a / gcd(a, b)*b; } //a*b = gcd*lcm
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = ;
const double eps = 1e-;
const int inf = 0x3f3f3f3f;
const int maxk = 1e6 + ;
const int maxn = 1e5 + ; int Size, root;
int ch[maxn<<][];
int f[maxn<<];
int key[maxn<<];
int cnt[maxn<<];
int siz[maxn<<]; inline void clear(int x)
{ ch[x][] = ch[x][] = f[x] = cnt[x] = key[x] = siz[x] = ; } //判断当前点是它父节点的左儿子还是右儿子
inline int get(int x)
{ return ch[f[x]][] == x; } //更新当前点size值(用于修改之后)
inline void update(int x)
{
if (x) {
siz[x] = cnt[x];
if (ch[x][]) siz[x] += siz[ch[x][]];
if (ch[x][]) siz[x] += siz[ch[x][]];
}
} inline void rotate(int x)
{
int old = f[x], oldf = f[old], which = get(x);
ch[old][which] = ch[x][which^]; f[ch[old][which]] = old;
f[old] = x; ch[x][which^] = old;
f[x] = oldf;
if (oldf)
ch[oldf][ch[oldf][]==old] = x;
update(old); update(x);
} inline void splay(int x)
{
for( int fa; (fa=f[x]); rotate(x))
if ( f[fa] )
rotate((get(x)==get(fa) ? fa : x));
root = x;
} inline void insert(int v)
{
if ( root == )
{
Size++; ch[Size][] = ch[Size][] = f[Size] = ; key[Size] = v;
cnt[Size] = ; siz[Size] = ; root = Size; return;
} int now = root, fa = ;
while ()
{
if (key[now] == v) {
cnt[now]++;
update(now); update(fa);
splay(now);
break;
}
fa = now;
now = ch[now][key[now]<v];
if (now == ) {
Size++;
ch[Size][] = ch[Size][] = ;
key[Size] = v; siz[Size] = ;
cnt[Size] = ; f[Size] = fa;
ch[fa][key[fa]<v] = Size;
update(fa);
splay(Size);
break;
}
}
} inline int find(int v)
{
int ans = , now = root;
while ()
{
if ( v < key[now] )
now = ch[now][];
else {
ans += (ch[now][] ? siz[ch[now][]] : );
if ( v == key[now] ) { splay(now); return ans+; } ans += cnt[now];
now = ch[now][];
}
}
} inline int findx(int x)
{
int now = root;
while ()
{
if ( ch[now][] && x <= siz[ch[now][]] )
now = ch[now][];
else {
int tmp = ( ch[now][] ? siz[ch[now][]] : ) + cnt[now]; if ( x <= tmp )
return key[now];
x -= tmp;
now = ch[now][];
}
}
} inline int pre()
{
int now = ch[root][];
while ( ch[now][] ) now = ch[now][];
return now;
} inline int next()
{
int now = ch[root][];
while ( ch[now][] ) now = ch[now][];
return now;
} inline void del(int x) {
int whatever = find(x);
if (cnt[root]>) { cnt[root]--; return; }
//Only One Point
if (!ch[root][] && !ch[root][]) { clear(root); root = ; return; }
//Only One Child
if (!ch[root][]) {
int oldroot = root; root = ch[root][]; f[root] = ; clear(oldroot); return;
}
else if (!ch[root][]) {
int oldroot = root; root = ch[root][]; f[root] = ; clear(oldroot); return;
}
//Two Children
int leftbig = pre(), oldroot = root;
splay(leftbig);
f[ch[oldroot][]] = root;
ch[root][] = ch[oldroot][];
clear(oldroot);
update(root);
return;
} int main()
{
int n, opt, x;
scanf("%d", &n);
for (int i = ; i <= n; ++i) {
scanf("%d%d", &opt, &x);
switch (opt) {
case : insert(x); break;
case : del(x); break;
case : printf("%d\n", find(x)); break;
case : printf("%d\n", findx(x)); break;
case : insert(x); printf("%d\n", key[pre()]); del(x); break;
case : insert(x); printf("%d\n", key[next()]); del(x); break;
}
} return ;
}

  BZOJ 1251(区间翻转和区间增加一个值V)

  这份代码比较清晰易懂

  https://blog.csdn.net/whai362/article/details/47298133(加了一些注释

/*bzoj 1251 序列终结者
题意:
给定一个长度为N的序列,每个序列的元素是一个整数。要支持以下三种操作:
1. 将[L,R]这个区间内的所有数加上V;
2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1;
3. 求[L,R]这个区间中的最大值;
最开始所有元素都是0。
限制:
N <= 50000, M <= 100000
思路:
伸展树
关键点:
1. 伸展树为左小右大的二叉树,所以旋转操作不会影响树的性质
2. 区间操作为:
int u = select(L - 1), v = select(R + 1);
splay(u, 0); splay(v, u); //通过旋转操作把询问的区间聚集到根的右子树的左子树下
因为伸展树为左小右大的二叉树,旋转操作后的所以对于闭区间[L, R]之间的所有元素都聚集在根的右子树的左子树下
因为闭区间[L, R],
1) 所以每次都要查开区间(L - 1, R + 1),
2) 所以伸展树元素1对应的标号为2,
3) 所以node[0]对应空节点,node[1]对应比所以元素标号都小的点,node[2 ~ n + 1]对应元素1 ~ n,node[n + 2]对应比所有元素标号都打的点,其中node[0], node[1], node[n + 2]都是虚节点,不代表任何元素。
*/
#include <iostream>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <algorithm>
#include <time.h> #define SIGMA_SIZE 26
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) (x&-x)
#define foe(i, a, b) for(int i=a; i<=b; i++)
#define fo(i, a, b) for(int i=a; i<b; i++);
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL;
inline LL LMax(LL a, LL b) { return a>b ? a : b; }
inline LL LMin(LL a, LL b) { return a>b ? b : a; }
inline LL lgcd(LL a, LL b) { return b == ? a : lgcd(b, a%b); }
inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; } //a*b = gcd*lcm
inline int Max(int a, int b) { return a>b ? a : b; }
inline int Min(int a, int b) { return a>b ? b : a; }
inline int gcd(int a, int b) { return b == ? a : gcd(b, a%b); }
inline int lcm(int a, int b) { return a / gcd(a, b)*b; } //a*b = gcd*lcm
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = ;
const double eps = 1e-;
const int inf = 0x3f3f3f3f;
const int maxk = 1e6 + ;
const int maxn = 1e5 + ; #define LS(n) node[(n)].ch[0]
#define RS(n) node[(n)].ch[1] struct Splay {
struct Node {
int fa, ch[];
bool rev;
int val, add, maxx, size;
void init(int _val) {
val = maxx = _val;
size = ;
add = rev = ch[] = ch[] = ;
}
} node[maxn];
int root; ///相当于线段树的pushup和pushdown
void pushUp(int n) {
node[n].maxx = Max(node[n].val, Max(node[LS(n)].maxx, node[RS(n)].maxx));
node[n].size = node[LS(n)].size + node[RS(n)].size + ;
} void pushDown(int n) {
if (n == ) return;
if (node[n].add) {
if (LS(n)) {
node[LS(n)].val += node[n].add;
node[LS(n)].maxx += node[n].add;
node[LS(n)].add += node[n].add;
}
if (RS(n)) {
node[RS(n)].val += node[n].add;
node[RS(n)].maxx += node[n].add;
node[RS(n)].add += node[n].add;
}
node[n].add = ;
}
if (node[n].rev) {
if (LS(n)) node[LS(n)].rev ^= ;
if (RS(n)) node[RS(n)].rev ^= ;
swap(LS(n), RS(n));
node[n].rev = ;
}
} ///kind = 0为左旋
///kind = 1为右旋
void rotate(int n, bool kind) {
int fn = node[n].fa;
int ffn = node[fn].fa;
node[fn].ch[!kind] = node[n].ch[kind];
node[node[n].ch[kind]].fa = fn; node[n].ch[kind] = fn;
node[fn].fa = n; node[ffn].ch[RS(ffn) == fn] = n;
node[n].fa = ffn;
pushUp(fn);
} void splay(int n, int goal) {
while (node[n].fa != goal) {
int fn = node[n].fa;
int ffn = node[fn].fa;
//三连pushDown
pushDown(ffn); pushDown(fn); pushDown(n);
bool rotate_n = (LS(fn) == n);
bool rotate_fn = (LS(ffn) == fn);
if (ffn == goal) rotate(n, rotate_n);
else {
if (rotate_n == rotate_fn) rotate(fn, rotate_fn);
else rotate(n, rotate_n);
rotate(n, rotate_fn);
}
}
pushUp(n);
if (goal == ) root = n;
} ///通过数组中的位置找在树中的位置
int select(int pos) {
int u = root;
pushDown(u);
while (node[LS(u)].size != pos) {
if (pos < node[LS(u)].size)
u = LS(u);
else {
pos -= node[LS(u)].size + ;
u = RS(u);
}
pushDown(u);
}
return u;
} int query(int L, int R) {
int u = select(L - ), v = select(R + );
splay(u, ); splay(v, u); ///通过旋转操作把询问的区间聚集到根的右子树的左子树下
return node[LS(v)].maxx;
} void pushUpdate(int L, int R, int val) {
int u = select(L - ), v = select(R + );
splay(u, ); splay(v, u);
node[LS(v)].val += val;
node[LS(v)].maxx += val;
node[LS(v)].add += val;
} void reverse(int L, int R) {
int u = select(L - ), v = select(R + );
splay(u, ); splay(v, u);
node[LS(v)].rev ^= ;
} ///返回子树的根节点
int build(int L, int R) {
if (L > R) return ;
if (L == R) return L;
int mid = (L + R) >> ;
int r_L, r_R;
LS(mid) = r_L = build(L, mid - );
RS(mid) = r_R = build(mid + , R);
node[r_L].fa = node[r_R].fa = mid;
pushUp(mid);
return mid;
} ///按照数组的下标顺序作为建树依据
///而不是按照数组内的元素大小做依据
void init(int n) {
///0号节点最大值和值都是负无穷
node[].init(-inf); node[].size = ;
node[].init(-inf);
node[n + ].init(-inf);
for (int i = ; i <= n + ; ++i)
node[i].init(); root = build(, n + );
node[root].fa = ; node[].fa = ;
LS() = root;
}
} splay_tree; int main() {
int n, m;
scanf("%d%d", &n, &m);
splay_tree.init(n);
for (int i = ; i < m; ++i) {
int op, l, r, v;
scanf("%d", &op);
if (op == ) {
scanf("%d%d%d", &l, &r, &v);
splay_tree.pushUpdate(l, r, v);
}
else if (op == ) {
scanf("%d%d", &l, &r);
splay_tree.reverse(l, r);
}
else {
scanf("%d%d", &l, &r);
printf("%d\n", splay_tree.query(l, r));
}
}
return ;
}

初识splay的更多相关文章

  1. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  2. BZOJ 3223: Tyvj 1729 文艺平衡树

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3628  Solved: 2052[Submit][Sta ...

  3. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  4. 初识Hadoop

    第一部分:              初识Hadoop 一.             谁说大象不能跳舞 业务数据越来越多,用关系型数据库来存储和处理数据越来越感觉吃力,一个查询或者一个导出,要执行很长 ...

  5. python学习笔记(基础四:模块初识、pyc和PyCodeObject是什么)

    一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...

  6. 初识IOS,Label控件的应用。

    初识IOS,Label控件的应用. // // ViewController.m // Gua.test // // Created by 郭美男 on 16/5/31. // Copyright © ...

  7. UI篇(初识君面)

    我们的APP要想吸引用户,就要把UI(脸蛋)搞漂亮一点.毕竟好的外貌是增进人际关系的第一步,我们程序员看到一个APP时,第一眼就是看这个软件的功能,不去关心界面是否漂亮,看到好的程序会说"我 ...

  8. Python导出Excel为Lua/Json/Xml实例教程(一):初识Python

    Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...

  9. BZOJ 1251: 序列终结者 [splay]

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discu ...

随机推荐

  1. LoadRunner关联通用函数的学习

    LoadRunner关联通用函数的学习 写这篇文章的时候,我先声明一下,本BLOG中的文章如果没有写出是转贴的一般就是本人原创. Loadrunner脚本中进行关联的时候,用到了一些函数,作用是把字符 ...

  2. Let's Encryt免费SSL证书申请[我司方案]

    Let's Encrypt颁发的证书是目前生产的大多数浏览器都信任的,您只需下载并运行Let's Encrypt客户端来生成一个证书即可. 在颁发证书之前,需要验证您的域名的所有权.首先,在您的主机上 ...

  3. response.text与content的区别

    在某些情况下来说,response.text 与 response.content 都是来获取response中的数据信息,效果看起来差不多.那么response.text 和 response.co ...

  4. 概率dp——hdu4089推公式+循环迭代

    迭代是化简公式的常用技巧 dp[i][j]表示队伍中有i人,tomato排在第j位出现情况2的概率,那么先推出公式再进行简化 dp[i][1]=p21*dp[i][i] + p41 j<=k : ...

  5. Form-Item Slot 自定义label内容

    <el-form-item> <span slot="label">体   重:</span> <el-input v-model=&qu ...

  6. 使用treeNMS管理及监控Redis

    Redis做为现在web应用开发的黄金搭担组合,大量的被应用,广泛用于存储session信息,权限信息,交易作业等热数据.做为一名有10年以上JAVA开发经验的程序员,工作中项目也是广泛使用了Redi ...

  7. 杂项-Maven-jna:JNA(Java Native Access)

    ylbtech-杂项-Maven-jna:JNA(Java Native Access) JNA(Java Native Access )提供一组Java工具类用于在运行期间动态访问系统本地库(nat ...

  8. Vue学习笔记——Vue-router

    转载:https://blog.csdn.net/guanxiaoyu002/article/details/81116616 第1节:Vue-router入门 .解读router/index.js文 ...

  9. ReadyAPI 教程和示例(一)

    原文:ReadyAPI 教程和示例(一) 声明:如果你想转载,请标明本篇博客的链接,请多多尊重原创,谢谢! 本篇使用的 ReadyAPI版本是2.5.0 通过下图你可以快速浏览一下主要的ReadyAP ...

  10. [NOIP2019模拟赛]数数(gcd)

    题目大意: 求l~r中有多少数与x互质,带单点修改 分析: 两个30的部分分很好打: ·n<=1000暴力O(nq)就好了 ·$a_i<=100$用树状数组维护每个x的前缀和就好了 100 ...