此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:

翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

输入

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n

输出

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

样例输入

5 3
1 3
1 3
1 4

样例输出

4 3 2 1 5

提示

n,m<=100000

非旋转treap相比于旋转treap支持区间操作,所以对于这道题只需要每次把树拆成[1~l-1]、[l~r]、[r+1~tot]三段,然后把[l~r]打上标记进行翻转,再把三段区间合并就行了。对于打标记的点只有在查到这个点时才翻转,如果一个点被打了两次标记就相当于不翻转。

最后附上代码.

指针版

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0,f=1; char c=nc(); while(!isdigit(c)) {if(c=='-') f=-1; c=nc();} while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}
ll rd2() {ll x=0,f=1; char c=nc(); while(!isdigit(c)) {if(c=='-') f=-1; c=nc();} while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}
int n,m;
int L,R;
struct treap
{int size;int rnd;int val;int rev;treap *ls,*rs;treap(){}treap(int k,treap *son){size=1;rnd=rand();val=k;ls=rs=son;rev=0;}void pushup(){size=ls->size+rs->size+1;}void pushdown(){if(rev){rev^=1;ls->rev^=1;rs->rev^=1;swap(ls,rs);}}
}tr[100010],nil;
typedef treap* node;
node root,cnt,null;
void init()
{nil=treap(0,NULL);null=&nil;null->ls=null->rs=null;null->size=0;root=null;cnt=tr;
}
node build(int x)
{*cnt=treap(x,null);return cnt++;
}
node merge(node x,node y)
{if(x==null){return y; }if(y==null){return x;}x->pushdown();y->pushdown();if(x->rnd<y->rnd){x->rs=merge(x->rs,y);x->pushup();return x;}else{y->ls=merge(x,y->ls);y->pushup();return y;}
}
void split(node rt,node &x,node &y,int k)
{if(rt==null){x=y=null;return ;}rt->pushdown();if(rt->ls->size>=k){y=rt;split(rt->ls,x,y->ls,k);rt->pushup();}else{x=rt;split(rt->rs,x->rs,y,k-rt->ls->size-1);rt->pushup();}
}
void print(node rt)
{rt->pushdown();if(rt->ls!=null){print(rt->ls);}printf("%d",rt->val);if(--n!=0){printf(" ");}if(rt->rs!=null){print(rt->rs);}
}
node build_tree(int l,int r)
{if(l==r){return build(l);}int mid=(l+r)>>1;return merge(build_tree(l,mid),build_tree(mid+1,r));
}
int main()
{init();n=rd();m=rd();root=build_tree(1,n);while(m--){L=rd();R=rd();node x,y,z;split(root,y,z,R);split(y,x,y,L-1);y->rev^=1;root=merge(merge(x,y),z);}print(root);
}

非指针版

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
using namespace std;
int n,m;
int r[100010];
int v[100010];
int s[100010][3];
int size[100010];
bool d[100010];
int root;
int tot;
int L,R;
int x,y,z;
int flag;
void pushup(int x)
{size[x]=size[s[x][0]]+size[s[x][1]]+1;
}
int build(int x)
{v[++tot]=x;r[tot]=rand();size[tot]=1;return tot;
}
void pushdown(int x)
{swap(s[x][0],s[x][1]);if(s[x][0]){d[s[x][0]]^=1;}if(s[x][1]){d[s[x][1]]^=1;}d[x]=0;
}
int merge(int x,int y)
{if(!x||!y){return x+y;}if(r[x]<r[y]){if(d[x]){pushdown(x);}s[x][1]=merge(s[x][1],y);pushup(x);return x;}else{if(d[y]){pushdown(y);}s[y][0]=merge(x,s[y][0]);pushup(y);return y;}
}
void split(int i,int k,int &x,int &y)
{if(!i){x=y=0;return ;}if(d[i]){pushdown(i);}if(size[s[i][0]]<k){x=i;split(s[i][1],k-size[s[i][0]]-1,s[i][1],y);}else{y=i;split(s[i][0],k,x,s[i][0]);}pushup(i);
}
void print(int x)
{if(!x){return ;}if(d[x]){pushdown(x);}print(s[x][0]);if(flag==0){printf("%d",v[x]);flag=1;}else{printf(" %d",v[x]);}print(s[x][1]);
}
int main()
{srand(12378);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){root=merge(root,build(i));}for(int i=1;i<=m;i++){scanf("%d%d",&L,&R);split(root,L-1,x,y);split(y,R-L+1,y,z);d[y]^=1;root=merge(merge(x,y),z);}print(root);return 0;
}

转载于:https://www.cnblogs.com/Khada-Jhin/p/9090646.html

BZOJ3223文艺平衡树——非旋转treap相关推荐

  1. 4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap

    国际惯例的题面: 这种维护排序序列,严格大于的进行操作的题都很套路...... 我们按照[0,k],(k,2k],(2k,inf)分类讨论一下就好. 显然第一个区间的不会变化,第二个区间的会被平移进第 ...

  2. luoguP5055 【模板】可持久化文艺平衡树 可持久化非旋转treap

    luoguP5055 [模板]可持久化文艺平衡树 可持久化非旋转treap 好题. Code: #include<bits/stdc++.h> using namespace std; # ...

  3. [NOIP]2017列队——旋转treap/非旋转treap

    Sylvia 是一个热爱学习的女孩子.  前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m.  为了便 ...

  4. [Codeforces702F]T-Shirts——非旋转treap+贪心

    题目链接: Codeforces702F 题目大意:有$n$种T恤,每种有一个价格$c_{i}$和品质$q_{i}$且每种数量无限.现在有$m$个人,第$i$个人有$v_{i}$元,每人每次会买他能买 ...

  5. BZOJ1251序列终结者——非旋转treap

    题目描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...

  6. luogu P3391 【模板】文艺平衡树(FHQ - treap,懒惰标记)

    整理的算法模板合集: ACM模板 我们把每个查询区间使用solit分裂成[1l−1][lr][r+1n][1~l-1][l~r][r+1~n][1 l−1][l r][r+1 n]三个区间. 再把[l ...

  7. BZOJ1112[POI2008]砖块Klo——非旋转treap

    题目描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另一柱.仓库无限大. 现在希望用最小次数的动作完成任 ...

  8. BZOJ1895Pku3580 supermemo——非旋转treap

    题目描述 给出一个初始序列fA1;A2;:::Ang,要求你编写程序支持如下操作: 1. ADDxyD:给子序列fAx:::Ayg的每个元素都加上D.例如对f1,2, 3,4,5g执行"AD ...

  9. [BJOI2019]送别——非旋转treap

    题目链接: [BJOI2019]送别 我们将每段墙的每一面看成一个点,将每个点与相邻的点(即按题中规则前进或后退一步能走到的点)连接.那么图中所有点就形成了若干个环,而添加一段墙或删除一段墙就是把两个 ...

最新文章

  1. CIO的职业之路应该朝向何方 做主角还是配角?
  2. python paramiko_Python Paramiko基本使用
  3. 关于系统重装的一件小事
  4. oracle本身的常用数据字典表
  5. 第八天2017/04/17(3、C++的几个语法)
  6. jdk jre jvm 关系
  7. MySQL 5.7.18 zip 文件安装过程
  8. python函数返回的元组_python – 从函数返回一个单独的元组元组
  9. 链表合并面试100题系列之18链表合并
  10. 深度linux安装make,linux下安装python3完整教程(依赖环境gcc,make,cmake,configure等详细解释)...
  11. ipad python编程软件_在iPad中运行Python
  12. pyspark分类算法之多层感知机神经网络分类器模型实践【MLPClassifier】
  13. windows 互斥量内核对象 Mutex
  14. python对TXT文本内容进行读写。
  15. postsql密码修改
  16. 陕西师大计算机考研专业考408嘛,2021考研计算机408考试趋势分析
  17. 文字转语音开源软件-espeak
  18. 生活小技巧:自己动手修理希捷 Expansion 移动硬盘
  19. php集成paypal付款流程,PHP整合PayPal支付_PHP教程
  20. 美国旅游带孩子怎么申请签证?

热门文章

  1. 优考试在线考试系统计算机,使用优考试在线考试系统解决企业员工考核评比
  2. Java正则表达式总结
  3. Spring Boot 设置 ASCII banner 艺术字
  4. Java 多线程 —— AQS 原理
  5. Java8————Optional
  6. 没有icon_ICON设计干货来啦~
  7. 《零基础》MySQL删除数据表(十)
  8. java自定义一个方法,用于返回两个整数的和
  9. gdb tui 安装_GDB 单步调试汇编
  10. 多个数据文件 mysql_mysql多实例(多个配置文件方式)