这题的建模有点不太一样,是按结点横坐标赋予键值的

同时每次rotate和splay时都要注意下往上往下更新

/*
先建立好splay tree,将结点按num/输入顺序排序,遍历时每次将当前结点提到根节点,输出其在splay树中排第几个
然后rev左子树,最后remove
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#include<algorithm>
#define maxn 100005
struct A{
int num,id;
bool operator < (const A &a) const {
if(num==a.num) return id<a.id;
return num<a.num;
}
}a[maxn];
int pre[maxn],ch[maxn][],size[maxn],keys[maxn],tot,root,n;
int rev[maxn];
inline void pushup(int r){
size[r]=size[ch[r][]]+size[ch[r][]]+;
}
void update(int r){//就是交换r的两个子区间
if(!r) return;
else {
swap(ch[r][],ch[r][]);
rev[r]^=;
}
}
inline void pushdown(int r){
if(rev[r]){//把左右子树rev
update(ch[r][]);
update(ch[r][]);
rev[r]=;
}
}
inline void newnode(int &r,int fa,int key){
r=key;
pre[r]=fa;
ch[r][]=ch[r][]=;
size[r]=;
keys[r]=key;
rev[r]=;
}
void build(int &r,int L,int R,int fa){
if(L>R) return;
int m=L+R>>;
newnode(r,fa,m);
build(ch[r][],L,m-,r);
build(ch[r][],m+,R,r);
pushup(r);
}
void init(){
root=tot=;
ch[root][]=ch[root][]=;
size[root]=;
rev[root]=;
build(root,,n,);
}
//rotate操作只会改变r,fa,ch[r][kind]三个结点
void rotate(int x,int kind){
int fa=pre[x];
pushdown(fa);
pushdown(x);
ch[fa][!kind]=ch[x][kind];
pre[ch[x][kind]]=fa;
if(pre[fa])
ch[pre[fa]][ch[pre[fa]][]==fa]=x;
pre[x]=pre[fa];
pre[fa]=x;
ch[x][kind]=fa;
pushup(fa);
pushup(x);
}
void splay(int r,int goal){
pushdown(r);
while(pre[r]!=goal){
if(pre[pre[r]]==goal){
pushdown(pre[r]);
pushdown(r);
rotate(r,ch[pre[r]][]==r);
}
else {
pushdown(pre[pre[r]]);
pushdown(pre[r]);
pushdown(r);
int fa=pre[r];
int kind=(ch[pre[fa]][]==fa);
if(ch[fa][kind]==r){//方向相反
rotate(r,!kind);
rotate(r,kind);
}
else {
rotate(fa,kind);
rotate(r,kind);
}
}
}
if(goal==) root=r;
pushup(r);
}
void remove(){//删掉根节点
if(ch[root][]==){
root=ch[root][];
pre[root]=;
}
else {
pushdown(root);
int tmp=ch[root][];
while(ch[tmp][])
pushdown(tmp),tmp=ch[tmp][];
splay(tmp,root);
ch[tmp][]=ch[root][];
pre[ch[root][]]=tmp;
root=tmp;
pre[root]=;
pushup(root);
}
} int main(){
while(scanf("%d",&n) && n){
init();
for(int i=;i<=n;i++)
scanf("%d",&a[i].num),a[i].id=i;
sort(a+,a++n);
for(int i=;i<n;i++){
splay(a[i].id,);//按权值大小遍历点
update(ch[root][]);//逆转区间
printf("%d ",i+size[ch[root][]]);//输出结点在当前伸展树中排的序号
remove();
}
printf("%d\n",n);
}
return ;
}

hdu1890 splay维护区间翻转的更多相关文章

  1. bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)

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

  2. BZOJ 3223: Tyvj 1729 文艺平衡树-Splay树(区间翻转)模板题

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

  3. 「Splay」区间翻转

    传送门:>Here< 解法分析 用splay来维护这个序列. 一直没有搞明白的是,这里的splay的节点究竟维护的是什么?是权值吗?肯定不是,因为区间是会翻转的,如果维护权值的话很快平衡树 ...

  4. 【模板】文艺平衡树(Splay) 区间翻转 BZOJ 3223

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 N,M<= ...

  5. 文艺平衡树 lg3391(splay维护区间入门)

    splay是支持区间操作的,先做这道题入个门 大多数操作都和普通splay一样,就不多解释了,只解释一下不大一样的操作 #include<bits/stdc++.h> using name ...

  6. splay(1区间翻转区间最值与区间修改)

    bzoj1251权限题 题目点这里,你懂得 直接上板子,这个要好好体会 操作是最经典的. #include <algorithm> #include <iostream> #i ...

  7. Splay(区间翻转) 模板

    洛谷:P3391 [模板]文艺平衡树(Splay) #include<cstdio> #include<iostream> #include<algorithm> ...

  8. 洛谷P3165 [CQOI2014]排序机械臂 Splay维护区间最小值

    可以将高度定义为小数,这样就完美的解决了优先级的问题. Code: #include<cstdio> #include<algorithm> #include<cstri ...

  9. hdu-1890-Robotic Sort splay区间翻转

    题意: 依次找第i大的数下标pos[i],然后将区间[i,pos[i]]翻转 分析: splay树区间翻转 // File Name: ACM/HDU/1890.cpp // Author: Zlbi ...

随机推荐

  1. SpringBoot 核心配置

    1. 入口类和 @SpringBootApplication Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的Java应用程序的入口方法 ...

  2. 盖得化工--selenium翻页测试

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  3. JavaSE学习总结(十五)—— Java反射与注解

    一.静态语言与动态语言 静态类型语言:是指在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型,某些具有类型推导能力的现代语言可能能够部分减轻这个要求.强类型 动态 ...

  4. C#常用的正则工具类写法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 数据库索引实现(B+,B-,hash)

    ★ B-Tree索引:每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历.B-Tree通常意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,很适合查找范围数据. ★ ...

  6. Spark2.1.0安装

    1.解压安装spark tar zxf spark-2.1.O-bin-2.6.0-CDH5.10.0.tgz 2.修改配置文件 vim /etc/profile export SPARK_HOME= ...

  7. u-boot移植(十三)---代码修改---支持文件系统及补丁制作

    一.烧写文件系统 1.1 jffs2烧写 1.下载文件系统:tftp 30000000 fs_mini_mdev.jffs2 2.擦除文件的块:nand erase.part rootfs 3.烧入文 ...

  8. C# redis简单的使用

    1.项目一:用于在Redis中添加数据 using System; using System.Collections.Generic; using System.Linq; using System. ...

  9. luogu P4360 [CEOI2004]锯木厂选址

    斜率优化dp板子题[迫真] 这里从下往上标记\(1-n\)号点 记\(a_i\)表示前缀\(i\)里面树木的总重量,\(l_i\)表示\(i\)到最下面的距离,\(s_i\)表示\(1\)到\(i-1 ...

  10. greenplum不能下载问题解决方法(转)

    到官网下载greenplum安装包的时候,可能会发现不能下载,提示: 出现这个问题的原因有几个方面: 最常见的原因是注册账号是填写了虚假或者无意义的信息,譬如名字是 123,地址是 abc. Pivo ...