题目背景

这是一道经典的Splay模板题——文艺平衡树。

题目描述

您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

输入输出格式

输入格式:

第一行为n,m(n,m<=100000) n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,⋯n−1,n) m表示翻转操作次数

接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n1≤l≤r≤n

输出格式:

输出一行n个数字,表示原始序列经过m次变换后的结果

输入输出样例

输入样例

  1. 5 3
  2. 1 3
  3. 1 3
  4. 1 4
输出样例

  1. 4 3 2 1 5
  2.  
  3. splay模板题,维护该序列的中序遍历不变,然后每次通过旋转节点使操作的区间变作一颗字树,然后打上标记即可。
    什么是splay?
    一棵伸展树......
    什么是伸展树?
    最近刚学,我个人的理解,大概就是一个能在不破坏二叉搜索树结构(即中序遍历始终为升序)的情况下
    通过旋转一个节点到他根节点位置使得操作区间恰好全部位于一棵子树内的方法。
  4.  
  5. 然后就打上标记,之后在类似线段树一样的pushdown传递信息就好了。
  6.  
  7. 代码如下:
  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cmath>
  6. #define LL long long
  7. #define mod
  8. #define mid (R+L>>1)
  9. #define M 2000010
  10. using namespace std;
  11. LL read(){
  12. LL nm=,oe=;char cw=getchar();
  13. while(!isdigit(cw)) oe=cw=='-'?-oe:oe,cw=getchar();
  14. while(isdigit(cw)) nm=nm*+(cw-''),cw=getchar();
  15. return nm*oe;
  16. }
  17. LL n,m,l[M],r[M],tp[M],ad,sz[M],tg[M],ace,a,b,p,q,cnt;
  18. bool flag=false;
  19. void pushdown(LL x){
  20. if(tg[x]==) return;
  21. tg[x]=,swap(l[x],r[x]);
  22. tg[l[x]]^=,tg[r[x]]^=;
  23. }
  24. void pushup(LL x){sz[x]=sz[l[x]]+sz[r[x]]+;}
  25. LL build(LL L,LL R,LL rt){
  26. if(L>R) return ;
  27. tp[mid]=rt,sz[mid]=;
  28. if(L==R) return L;
  29. l[mid]=build(L,mid-,mid);
  30. r[mid]=build(mid+,R,mid);
  31. sz[mid]+=sz[l[mid]]+sz[r[mid]];
  32. return mid;
  33. }
  34. void rotate(LL x){
  35. if(ace==x) return;
  36. LL top=tp[x];
  37. pushdown(top),pushdown(x);
  38. if(top==ace) ace=x,tp[x]=n+,tp[top]=x;
  39. else{
  40. if(l[tp[top]]==top) l[tp[top]]=x;
  41. else r[tp[top]]=x;
  42. tp[x]=tp[top],tp[top]=x;
  43. }
  44. if(l[top]==x) l[top]=r[x],tp[r[x]]=top,r[x]=top;
  45. else r[top]=l[x],tp[l[x]]=top,l[x]=top;
  46. pushup(top),pushup(x);
  47. }
  48. void oper(LL x){
  49. if(x==ace||tp[x]==ace){return;}
  50. LL top=tp[x];
  51. pushdown(top);
  52. if(tp[top]==ace) rotate(x);
  53. else if(l[l[tp[top]]]==x||r[r[tp[top]]]==x) rotate(top);
  54. else rotate(x);
  55. }
  56. LL find(LL x,LL pos){
  57. pushdown(x);
  58. if(sz[l[x]]==pos-) return x;
  59. if(sz[l[x]]<pos-) return find(r[x],pos-sz[l[x]]-);
  60. else return find(l[x],pos);
  61. }
  62. void ans(LL x){
  63. if(x==) return;
  64. pushdown(x);
  65. ans(l[x]);
  66. if(x<n&&x>){
  67. if(flag) printf(" ");
  68. flag=true;
  69. printf("%lld",x-);
  70. }
  71. ans(r[x]);
  72. }
  73. int main(){
  74. n=read()+,m=read(),ace=build(,n,n+);
  75. while(m--){
  76. a=read(),b=read();
  77. p=find(ace,a),q=find(ace,b+);
  78. while(tp[q]!=ace&&q!=ace) oper(q);
  79. if(q!=ace) rotate(q);
  80. while(tp[p]!=ace) oper(p);
  81. tg[r[p]]^=;
  82. }
  83. ans(ace);
  84. return ;
  85. }
  1.  

我这里还是写的比较模糊,我也是通过了解别人的博客才理解了splay

就是这个 -> http://blog.csdn.net/skydec/article/details/20151805

洛谷 P3391 【模板】文艺平衡树的更多相关文章

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

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  2. 【洛谷P3391】文艺平衡树——Splay学习笔记(二)

    题目链接 Splay基础操作 \(Splay\)上的区间翻转 首先,这里的\(Splay\)维护的是一个序列的顺序,每个结点即为序列中的一个数,序列的顺序即为\(Splay\)的中序遍历 那么如何实现 ...

  3. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  4. 洛谷.3369.[模板]普通平衡树(fhq Treap)

    题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  5. 洛谷 P3391 模板Splay

    #include<bits/stdc++.h> using namespace std; #define maxn 200000 int read() { ,w=; ;ch=getchar ...

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

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

  7. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

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

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

  9. 洛谷P3391文艺平衡树(Splay)

    题目传送门 转载自https://www.cnblogs.com/yousiki/p/6147455.html,转载请注明出处 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 ...

  10. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

随机推荐

  1. Druid连接池

    Druid 连接池简介 Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.J ...

  2. cf290-2015-2-3总结与反思(dfs判断无向图是否有环)

    bool dfs(int i,int pre) { visit[i]=true; ;j<=v;j++) if(g[i][j]) { if(!visit[j]) return dfs(j,i); ...

  3. springcloud干货之服务消费者(ribbon)

    本章介绍springcloud中的服务消费者 springcloud服务调用方式有两种实现方式: 1,restTemplate+ribbon, 2,feign 本来想一篇讲完,发现篇幅有点长,所以本章 ...

  4. 推荐系统架构-(附ppt&代码)

    Part1.乐视网视频推荐系统 推荐系统:和传统的推荐系统架构无异(基础建模+规则) 数据模块特点:用户反馈服务数据->kv 缓存->log存储 行为日志->解析/聚合->se ...

  5. 【计算机网络】 一个小白的DNS学习笔记

    参考书籍 <计算机网络-自顶向下>  作者 James F. Kurose   DNS的作用   DNS是因特网的目录服务 DNS是因特网的目录服务,它提供了主机名到IP地址映射的查询服务 ...

  6. git上传遇到 GitHub could not read Username 的解决办法

    Gitversion 1.8.5.2 执行git push命令异常,如下: Push failed Failed with error: unable to read askpass response ...

  7. svn 提交 working copy is not up-to-date

    svn在提交时报错信息如下: working copy is not up-to-date svn:commit failed(details follow): svn:file "xxxx ...

  8. [http服务]

    [http服务] CentOS 6 httpd 程序环境 记录了httpd的主进程编号: v 主程序文件: /usr/sbin/httpd /usr/sbin/httpd.worker /usr/sb ...

  9. oracle数据库无监听程序

    在电脑---服务---启动oracle  tns 如果还是出现错误的话,找到Net Manager,将网络的ip监听删除,将本机的主机名配好,即可打开tns服务

  10. .10-Vue源码之Watcher(1)

    上一节最后再次调用了mount函数,我发现竟然跳到了7000多行的那个函数,之前我还说因为声明早了被覆盖,看来我错了! 就是这个函数: // Line-7531 Vue$3.prototype.$mo ...