[Tyvj 1729]文艺平衡树
2015-08-07 19:45
218 查看
P1729 文艺平衡树
时间: 1000ms / 空间: 131072KiB / Java类名: Main
此为平衡树系列第二道:文艺平衡树
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
翻转一个区间,例如原有序序列是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
Splay的特殊应用,当前点的size域代表的是它在数列中的位置,当前点的下标即为此数(可以再维护一个域,只不过这个域和下标是相等的)。所以我们需要写一个查询第k大来旋转更改区间,每次查询的时候要把标记向下传递。此时再进行Splay只需要pushdown一下当前点就可以了,因为上面都木有标记了!
时间: 1000ms / 空间: 131072KiB / Java类名: Main
背景
此为平衡树系列第二道:文艺平衡树
描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是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次变换后的结果
测试样例1
输入
5 3 1 3
1 3
1 4
输出
4 3 2 1 5
备注
n,m<=100000 Splay的特殊应用,当前点的size域代表的是它在数列中的位置,当前点的下标即为此数(可以再维护一个域,只不过这个域和下标是相等的)。所以我们需要写一个查询第k大来旋转更改区间,每次查询的时候要把标记向下传递。此时再进行Splay只需要pushdown一下当前点就可以了,因为上面都木有标记了!
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100010 using namespace std; struct Tree{ int ch[2],rev,fa,siz; #define c(x,y) tree[x].ch[y] #define rev(x) tree[x].rev #define fa(x) tree[x].fa #define siz(x) tree[x].siz }tree[maxn]; int n,root,m; void Pushup(int x){ if(x)siz(x)=siz(c(x,0))+siz(c(x,1))+1; } void Pushdown(int x){ if(rev(x)){ swap(c(x,0),c(x,1)); rev(c(x,0))^=1;rev(c(x,1))^=1; rev(x)=0; } } void Rotate(int p,int x){ int mark=p==c(x,1),y=c(p,mark^1),z=fa(x); if(x==c(z,0))c(z,0)=p; if(x==c(z,1))c(z,1)=p; if(y)fa(y)=x; fa(p)=z;fa(x)=p;c(p,mark^1)=x;c(x,mark)=y; Pushup(x); } void Splay(int p,int k){ Pushdown(p); while(fa(p)!=k){ int x=fa(p),y=fa(x); if(y==k)Rotate(p,x); else if(x==c(y,0)^p==c(x,0))Rotate(p,x),Rotate(p,y); else Rotate(x,y),Rotate(p,x); }if(!k)root=p;Pushup(p); } int Kth(int k){ int now=root; while(now){ Pushdown(now); if(k>siz(c(now,0))){ k-=siz(c(now,0))+1; if(!k)return now; now=c(now,1); }else now=c(now,0); }return 0; } void Rever(int l,int r){ l=Kth(l),r=Kth(r+2); Splay(l,0);Splay(r,l); rev(c(r,0))^=1; } void Build(int l,int r,int f){ if(l>r)return; if(l==r){ if(f)c(f,l>f)=l; fa(l)=f; siz(l)=1; return; } int mid=(l+r)>>1; Build(l,mid-1,mid); Build(mid+1,r,mid); if(f)c(f,mid>f)=mid;fa(mid)=f; Pushup(mid); } void Print(int x){ if(!x)return; Pushdown(x); Print(c(x,0)); if(x!=1&&x!=n+2)printf("%d ",x-1); Print(c(x,1)); } int main(){ scanf("%d%d",&n,&m); int l,r; Build(1,n+2,0); root=(n+3)>>1; for(int i=1;i<=m;i++){ scanf("%d%d",&l,&r); Rever(l,r); } Print(root); return 0; }
相关文章推荐
- Intellij--File Status Highlights文件高亮规则
- HMM隐马尔可夫
- POJ 1316 Self Numbers 筛选模拟
- POJ2299-Ultra-QuickSort 解题心得
- Log4j.properties配置详解
- HDU 1406 完数
- 认识Service
- QT下实现将图片从一个文件拷贝到另一个文件夹
- Windows下命令安装MySQL.zip压缩包以及修改MySQL密码
- UOJ #5. 【NOI2014】动物园 扩大KMP
- POJ 1922 Ride to School 简单模拟
- Codeforces Gym 100418K Cards 暴力打表
- Scala学习笔记-14
- 外键查询及删除
- swirl 6: Subsetting Vectors
- hdu 5355 Cake dfs暴搜 构造
- HashMap和HashSet的区别
- HDU 1201 18岁生日
- POJ 2017 Speed Limit 简单模拟
- sizeof运算符