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 ;
}

最新文章

  1. HTML5教程之html 5 本地数据库(Web Sql Database)
  2. 在web.xml注册applicationContext.xml配置文件
  3. matlab mesh visualization
  4. Java中封装、继承和多态
  5. shell脚本编译安装LAMP环境
  6. http状态码详细说明
  7. Mysql_mysql 性能分析及explain用法
  8. 基础canvas应用-钟表绘制
  9. ORACLE 表连接详解
  10. 关于图计算和graphx的一些思考[转]
  11. [翻译] 编写高性能 .NET 代码--第五章 通用编码与对象设计 -- 类 vs 结构体
  12. eclipse 下使用git clone
  13. StringMVC @RequestMapping method属性
  14. 用SQL语言操作数据
  15. day-3 python多线程编程知识点汇总
  16. MongoDB 高级索引
  17. 手机web——自适应网页设计(html/css控制)【转】
  18. Odoo薪酬管理 公式配置
  19. 自动化运维 --- git
  20. MySQL 之 数据操作

热门文章

  1. QD程序设计比赛游记
  2. magento2.2.3 根据产品ID获取栏目名称的正确调用方式
  3. pandas模块的数据操作
  4. 了解SIT和UAT的基本内涵
  5. hdu 2187 悼念512汶川大地震遇难同胞——老人是真饿了(贪心)
  6. [CF1303B] National Project - 数学
  7. 微信小程序报错TypeError: this.setData is not a function
  8. 2级搭建类204-Oracle 12cR2 SI ASM 图形化搭建(RHEL7.6)
  9. 134.cookie、session的工作机制
  10. 压缩软件推荐(bandizip)