文艺平衡树 lg3391(splay维护区间入门)
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维护区间入门)的更多相关文章
- bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2202 Solved: 1226[Submit][Sta ...
- 【模板】文艺平衡树(Splay) 区间翻转 BZOJ 3223
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 N,M<= ...
- splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)
先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...
- P3391 【模板】文艺平衡树(Splay)新板子
P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...
- fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)
题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...
- 洛谷 P3391 【模板】文艺平衡树(Splay)
题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...
- 洛谷 P3391【模板】文艺平衡树(Splay)
题目背景 这是一道经典的Splay模板题--文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...
- 文艺平衡树(Splay)
题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...
- 洛谷P3391 【模板】文艺平衡树(Splay)(FHQ Treap)
题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...
随机推荐
- MacBook Pro安装VMware Fusion 11
下载地址 https://www.vmware.com/cn/products/fusion/fusion-evaluation.html 序列号 TX1NF-PPVRW-A1XAX-X5PVZ-Q7 ...
- vue-infinite-loading 过滤器tab正确使用
业务逻辑涉及loadmore,filter和tab切换,框架是vue,使用vue-infinite-loading中的一点经历. identifier 一开始并没有重视这个参数,只是他的官网说iden ...
- Java WebService 简单实例-服务端和客户端
转载自ITeye:https://www.iteye.com/topic/1135747/
- Windows 使用 TCPing 工具来获取 TCP延迟、端口通顺情况、已禁Ping服务
https://elifulkerson.com/projects/tcping.php
- PHP0008:PHP基础-数组
- 在javascript编程语言中,数据类型boolean的相关知识
一. 1.字符串类型: 空字符串返回false,非空字符串均返回true; 2.数值类型: 0或NaN返回false,其他数值返回true; 3.布尔类型: false返回false,true返回tr ...
- Pycharm的项目文件名是红色的原因及解决办法
今天在继续学习Python时,打开Pycharm后,发现有一个项目下的项目文件名是红色的,如下图: 刚开始我以为是我升级 Pycharm导致的,但我并没有急着去解决,因为并不会影响我执行代码等.当我修 ...
- 2020牛客寒假算法基础集训营4-F树上博弈
链接:https://ac.nowcoder.com/acm/contest/3005/F来源:牛客网 题目描述 现有一个 n 个点,n-1条边组成的树,其中 1 号点为根节点. 牛牛和牛妹在树上玩游 ...
- HTML/JavaScript实现地图以鼠标为圆心缩放和移动
代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- pandas玩转excel-> (1)如何利用pandas创建excel数据文件
#在Anaconda3 的Spyder中 #定义pandas模块为pd import pandas as pd #创建一个新的DataFrame对象,定义这个对象中有两个字段:ID和Name, ...