splay是支持区间操作的,先做这道题入个门

大多数操作都和普通splay一样,就不多解释了,只解释一下不大一样的操作

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
inline int read(){
int w=,f=;
char ch=getchar();
while(ch<''||ch>''){
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<=''){
w=(w<<)+(w<<)+ch-;
ch=getchar();
}
return w*f;
}
int n,m,tot,cnt,root;
struct node{
int ch[],sum,cnt,val,f,rev;//比普通平衡树多一个lazy tag
}st[];
inline void push_up(int p){
st[p].sum=st[st[p].ch[]].sum+st[st[p].ch[]].sum+st[p].cnt;
}
inline bool identify(int p){
return st[st[p].f].ch[]==p;
}
inline void connect(int x,int fa,int son){
st[x].f=fa;st[fa].ch[son]=x;return;
}
inline void rotate(int x){
int y=st[x].f;int z=st[y].f;
int yson=identify(x);int zson=identify(y);
int b=st[x].ch[yson^];
connect(b,y,yson);connect(y,x,(yson^));connect(x,z,zson);
push_up(y);push_up(x);return;
}
inline void splay(int x,int goal){
while(st[x].f!=goal){
int y=st[x].f;int z=st[y].f;
int yson=identify(x);int zson=identify(y);
if(z!=goal){
if(yson==zson) rotate(y);
else rotate(x);
}
rotate(x);
}
if(!goal) root=x;
return;
}
inline void insert(int x){
int now=root;int f=;
while(st[now].val!=x&&now){
f=now;
now=st[now].ch[x>st[now].val];
}
if(now){
st[now].cnt++;
}
else{
tot++;now=tot;
if(f){
st[f].ch[x>st[f].val]=now;
}
st[now].ch[]=st[now].ch[]=;
st[now].cnt=st[now].sum=;
st[now].val=x;st[now].f=f;
}
splay(now,);return;
}
inline void push_down(int p){
int ls=st[p].ch[];int rs=st[p].ch[];
if(st[p].rev){
swap(st[p].ch[],st[p].ch[]);
st[st[p].ch[]].rev^=;
st[st[p].ch[]].rev^=;
st[p].rev=;
}
}
inline void find(int x){
int now=root;if(!now) return;
while(st[now].val!=x&&st[now].ch[x>st[now].val]){
now=st[now].ch[x>st[now].val];
}
splay(now,);return;
}
inline int Next(int x,int f){
find(x);int now=root;
if(st[now].val<x&&!x) return now;
if(st[now].val>x&&x) return now;
now=st[now].ch[f];
while(st[now].ch[f^]) now=st[now].ch[f^];
return now;
}
inline int k_th(int x){
int now=root;
if(st[now].sum<x) return false;
while(true){
push_down(now);//在查找的时候记得下移标记
int ls=st[now].ch[];
if(x>st[ls].sum+st[now].cnt){
x-=st[ls].sum+st[now].cnt;
now=st[now].ch[];
}
else if(x<=st[ls].sum){
now=ls;
}
else return now;//这个地方把返回原值改成返回位置
}
}inline void rev(int l,int r){
int x=k_th(l-);int y=k_th(r+);
splay(x,);splay(y,x);
st[st[y].ch[]].rev^=;
}//翻转的操作就是将l-1转到根上,r+1转到根的右儿子,然后l到r这个区间就是根右儿子的左儿子(比较绕,可以画个图想一想
inline void output(int p){
push_down(p);
if(st[p].ch[]) output(st[p].ch[]);
if(st[p].val>=&&st[p].val<=n) printf("%d ",st[p].val);
if(st[p].ch[]) output(st[p].ch[]);
}//输出的时候下推一下标记,输出顺序就是二叉树的顺序
int main(){
n=read();m=read();int i,j,k;
insert(INF);insert(-INF);
for(i=;i<=n;i++){
insert(i);
}
while(m--){
int x,y;x=read();y=read();
rev(x+,y+);
}
output(root);
return ;
}

文艺平衡树 lg3391(splay维护区间入门)的更多相关文章

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

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

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

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

  3. splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)

    先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...

  4. P3391 【模板】文艺平衡树(Splay)新板子

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

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

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

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

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

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

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

  8. 文艺平衡树(Splay)

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

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

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

随机推荐

  1. Android实战项目——家庭记账本(二)

    今天主要是对昨天做的添加账单信息的功能做了完善,实现了数据库的相关操作,如图是对已添加的账单信息的总结显示. 目前实现了通过日期进行汇总的功能,如上图中的各项item就是通过对所有账单信息进行按日期汇 ...

  2. Java模拟客户端向服务器上传文件

    先来了解一下客户端与服务器Tcp通信的基本步骤: 服务器端先启动,然后启动客户端向服务器端发送数据. 服务器端收到客户端发送的数据,服务器端会响应应客户端,向客户端发送响应结果. 客户端读取服务器发送 ...

  3. 剑指offer-面试题36-二叉搜索树与双向链表-中序遍历

    /* 题目: 将二叉搜索树转化为排序的双向链表,不能创建新的节点, 只能调整节点的指向,返回双向链表的头节点. */ /* 思路: 递归. 二叉搜索树的中序遍历得到的序列是递增序列. 左子树left& ...

  4. centos7 升级sqlite3

    升级sqlite3 官网 点击 1.下载源码 wget https://www.sqlite.org/2019/sqlite-autoconf-3300100.tar.gz 2.解压,编译 .tar. ...

  5. Byte 一个字节的数据大小范围为什么是-128~127

    一个字节是8位,最高位是符号位,最高位为0则是正数.最高位为1则是负数 如果一个数是正数,最大数则为:01111111,转为十进制为127, 如果一个数是负数,按照一般人都会觉得是11111111,转 ...

  6. Pikachu-Unsafe Fileupload(不安全的文件上传)

    不安全的文件上传漏洞概述 文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像.上传附件等等.当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型.后缀名.大小等等 ...

  7. MySQL在大数据、高并发场景下的SQL语句优化和"最佳实践"

    本文主要针对中小型应用或网站,重点探讨日常程序开发中SQL语句的优化问题,所谓“大数据”.“高并发”仅针对中小型应用而言,专业的数据库运维大神请无视.以下实践为个人在实际开发工作中,针对相对“大数据” ...

  8. 网络共享服务(三)之SAMBA

    前面说到了FTP和NFS,由于FTP是客户端和服务器基于ftp应用协议进行交换数据的,它不支持挂载共享目录的方式,而NFS又不支持跨平台,所以就催生了第三种网络共享服务:samba Samba是在Li ...

  9. SDN的深入思考(1):SDN的核心本质到底是什么?

    原文链接:https://blog.csdn.net/maijian/article/details/41744535 SDN的概念从提出到现在已经过了4年多了,但是关于SDN最基本的问题,“什么是S ...

  10. 【H5适配 笔记1】rem适配

    设备像素比(dpr)= 物理像素(手机渲染像素.分辨率)/设备独立像素(手机所显示元素的大小) 视口(viewport) 布局视口(获取浏览器布局视口高度,包括内边距,但不包括垂直滚动条.边框和外边距 ...