Splay

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
struct node *nil;//防止真的访问了NULL导致re(从零开始的编码生活)
struct node
{int val;//节点值int size;//以他为根的节点的子树节点个数(包括他自己)int flag;//懒标记node *ch[2];//左右儿子void sum()//重新计算size{size=1+ch[0]->size+ch[1]->size;//因为这里我们定义了不会re的无意义空地址。所以就不用判断}int cmp(int kth)//比较该往那颗子树上走{int s=ch[0]->size;if(kth==s+1)//就是当前根return -1;return (kth <= s ? 0 : 1);}
}*root;
int n,m;
void init()//初始化
{nil=new node;nil->flag=0;nil->size=0;nil->val=0;nil->ch[0]=nil->ch[1]=nil;root=nil;
}
node *New()//申请内存并初始化
{node *res=new node;res->size=1;res->flag=0;res->ch[0]=res->ch[1]=nil;return res;
}
void rotato(node* &now,int base)//旋转函数。应为这里是引用指针。所以直接指向就可以了。不用顾忌其他东西辣( ̄▽ ̄)~*
{node *k=now->ch[base^1];//利用异或进行取反now->ch[base^1]=k->ch[base];k->ch[base]=now;now->sum();//先计算被旋转下去的根,再计算新的根k->sum();now=k;
}
void build(node* &now,int l,int r)//建树,一定要引用。l为左边界。
{if(l>r)return ;int mid=(l+r)>>1;if(now==nil)//如果为空就动态申请,当然也可以动态删除{now=New();now->val=mid;}build(now->ch[0],l,mid-1);//左右递归的建树build(now->ch[1],mid+1,r);now->sum();return ;
}
void push_down(node* &now)//下放lazy tag
{if(now!=nil&&now->flag){swap(now->ch[0],now->ch[1]);now->ch[0]->flag^=1;now->ch[1]->flag^=1;now->flag=0;}return ;
}
void visit(node* &now)//中序便利
{if(now==nil)return ;push_down(now);visit(now->ch[0]);if(now->val!=0&&now->val!=n+1)printf("%d ",now->val);visit(now->ch[1]);
}
void splaykth(node* &now,int kth)//将以now为根的树中把第kth小的旋转到根上
{push_down(now);int d=now->cmp(kth);if(d!=-1){push_down(now->ch[d]);if(d==1)kth-=now->ch[0]->size+1;//换根要重新计算kth,下同int d2=now->ch[d]->cmp(kth);if(d2!=-1){if(d2==1)kth-=now->ch[d]->ch[0]->size+1;splaykth(now->ch[d]->ch[d2],kth);if(d==d2)rotato(now,d2^1),rotato(now,d^1);//一字型elserotato(now->ch[d],d2^1),rotato(now,d^1);//之字形}elserotato(now,d^1);//单旋}
}//其实这里应该要判空的,以防止非法情况出现。不过根据这个题。我们调用的时候没有非法情况
void Reverse(int l,int r)//翻转,这里因为有可能涉及到将1~n都翻转一遍。所以我们可以建两个哨兵节点,位置在0,n+1上。
{       //将l~r翻转//l,r为第l个数到第r个数(1~n中)splaykth(root,l);//把l-1翻上来splaykth(root->ch[1],r+1-root->ch[0]->size);//把r+1翻到右子树根的位置上。这样根节点右儿子的左子树上就是l~r。root->ch[1]->ch[0]->flag^=1;//打上懒标记return ;
}
int main()
{init();scanf("%d%d",&n,&m);build(root,0,n+1);int a,b;for(int i=1;i<=m;i++){scanf("%d%d",&a,&b);Reverse(a,b);}/*splaykth(root,7);cout<<root->val;*/visit(root);//中序遍历一波
}

转载于:https://www.cnblogs.com/Lance1ot/p/9047440.html

P3391 【模板】文艺平衡树(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 文艺平衡树-Splay树(区间翻转)模板题

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 6881  Solved: 4213 [Submit][S ...

  3. BZOJ 3223: Tyvj 1729 文艺平衡树(splay)

    速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...

  4. 文艺平衡树 Splay 学习笔记(1)

    (这里是Splay基础操作,reserve什么的会在下一篇里面讲) 好久之前就说要学Splay了,结果苟到现在才学习. 可能是最近良心发现自己实在太弱了,听数学又听不懂只好多学点不要脑子的数据结构. ...

  5. fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)...

    题面: [模板]文艺平衡树(Splay) 题解:无 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<iostr ...

  6. 洛谷 P3391 【模板】文艺平衡树

    题目背景 这是一道经典的Splay模板题--文艺平衡树. 题目描述 您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4 ...

  7. 【luogu P5055】【模板】可持久化文艺平衡树

    [模板]可持久化文艺平衡树 题目链接:luogu P5055 题目大意 要你维护插入,删除,区间翻转,区间求和. 但要求可持续化,即每次操作在一个历史版本上进行,且会产生一个新的历史版本 思路 看到题 ...

  8. 文艺平衡树(Splay)

    题目背景 这是一道经典的Splay模板题--文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...

  9. P5055 【模板】可持久化文艺平衡树

    P5055 [模板]可持久化文艺平衡树 突然发现fhq_treap也是可以支持区间翻转的,所以基本上和其他平衡树是一样的,而且还满足重量平衡树的性质,真是太优秀了,只不过常数稍微比较大. 然后这里我们 ...

  10. 【Splay】文艺平衡树(金牌导航 Splay-2)

    #文艺平衡树 金牌导航 Splay-2 题目大意 给你一个1~n的序列,然后对序列的区间做若干次翻转,问你最后的序列 输入样例 5 3 1 3 1 3 1 4 输出样例 4 3 2 1 5 数据范围 ...

最新文章

  1. FreeNas安装、初始化和存储池设置
  2. C++ 发手机短信(很易很简单)
  3. 有序数组给定始末的中位数c++
  4. 收下这12篇最新论文,炼丹不愁没灵感 | 本周值得读
  5. 如何找到某个 ABAP structure 某字段的源头来自哪个数据库表
  6. BeanUtils自定义转换器
  7. datetime模块日期转换和列表sorted排序
  8. 入门javascript_Espruino入门,Espruino是用于微控制器JavaScript解释器
  9. python 字符串删除重复_leetcode No.1047 删除字符串中的所有相邻重复项
  10. linux clone函数ptid,pthread_create到ret_fast_syscalls 参数和栈的变化
  11. 2021 年 7 月程序员工资统计,最赚钱的岗位出炉。。
  12. 网站正在建设中_网站建设中如何设计更能吸引用户
  13. kali安装步骤失败 选择并安装软件_交通仿真建模软件Vissim7.0/6.0/5.3安装步骤
  14. iTextSharp操作PDF
  15. python 机器翻译免费接口调用
  16. CSDN——缩进两个字符
  17. 【招聘】上海微创医疗机器人集团 - 软件工程师/图像算法工程师
  18. 从语言之争到年龄焦虑
  19. 找工作与找对象的关系
  20. 警告“未引用的形参/局部变量”的消除方法

热门文章

  1. 用border-width,border-color画三角形
  2. 9. Palindrome Number
  3. hdu4539 郑厂长系列故事——排兵布阵 + POJ1158 炮兵阵地
  4. 【五线谱】符干朝向与连音线 ( 符干朝向 | 第三线以下符干朝上 | 第三线以上符干朝下 | 连音线 )
  5. 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | RawDexFile.cpp 分析 | dvmRawDexFileOpen函数读取 DEX 文件 )
  6. 【Java 并发编程】线程池机制 ( 线程池阻塞队列 | 线程池拒绝策略 | 使用 ThreadPoolExecutor 自定义线程池参数 )
  7. 【SeeMusic】购买付费版本 ( 进入购买页面 | 购买流程 )
  8. 【计算机网络】网络层 : 总结 ( 功能 | 数据交换 | IP 数据报 | IPv4 地址 | IPv6 地址 | 路由选择协议 | 路由算法 )★★★
  9. 【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | ActivityThread 主函数分析 | 应用初始化 | 启动优化项目 )
  10. 【Android NDK 开发】JNI 引用 ( 局部引用 | 局部引用作用域 | 局部引用产生 | 局部引用释放 | 代码示例)