文艺平衡树笔记——fhq
文艺平衡树笔记——
P3391 【模板】文艺平衡树#
题意#
- 给你一个数列
,要求支持一种操作:- 给定一个区间
,翻转这个区间。 - 比如,
,翻转 之后,得到 。
- 给定一个区间
- 最后输出翻转后的序列。
做法#
-
我们继续用
做。 -
为啥不行
-
我们让
向线段树学习。- 我们给
加一个线段树的lazy_tag
,表示这棵子树要不要被翻转。 - 然后经典的标记下放。
- 下放时要异或,不是加,不是减。
- 我们给
-
我们考虑分裂操作:
- 用大小分裂,可以看这篇博客
-
我们考虑合并操作
- 在合并时加上标记下放即可
-
我们考虑翻转操作
- 我们先按大小
把原树分裂成 和 ,再按 把 分裂成 和 。 - 为啥是这俩数捏?
- 我们对
操作,那么在 前面还有 个数,而我们要操作的数有 个。 - 就这样了。
- 我们先按大小
-
我们考虑输出
- 就是中序遍历啦
#
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,m;
struct node{//fhq节点定义
int l,r,key,size,val;
bool tag;
}fhq[maxn];
int cnt=0,root=0;
int newnode(int val){//新建节点
fhq[++cnt].val=val;
fhq[cnt].key=rand();
fhq[cnt].size=1;
fhq[cnt].l=fhq[cnt].r=fhq[cnt].tag=0;
return cnt;
}
void update(int x){//更新大小
fhq[x].size=fhq[fhq[x].l].size+fhq[fhq[x].r].size+1;
}
void lazy_tag(int x){//标记下放
if(!fhq[x].tag)return;
swap(fhq[x].l,fhq[x].r);
fhq[fhq[x].l].tag^=1;
fhq[fhq[x].r].tag^=1;
fhq[x].tag=0;
}
void split(int now,int size,int &x,int &y){//大小分裂
if(!now)x=y=0;
else{
lazy_tag(now);
if(fhq[fhq[now].l].size<size){
x=now;
split(fhq[now].r,size-fhq[fhq[now].l].size-1,fhq[now].r,y);
}
else{
y=now;
split(fhq[now].l,size,x,fhq[now].l);
}
update(now);
}
}
int merge(int x,int y){//合并
if(!x||!y)return x|y;
if(fhq[x].key<fhq[y].key){
lazy_tag(x);
fhq[x].r=merge(fhq[x].r,y);
update(x);
return x;
}
else{
lazy_tag(y);
fhq[y].l=merge(x,fhq[y].l);
update(y);
return y;
}
}
void rev(int l,int r){//翻转
int x,y,z;
split(root,l-1,x,y);
split(y,r-l+1,y,z);
fhq[y].tag=1;
root=merge(merge(x,y),z);
}
void print(int now){//输出
if(!now)return;
lazy_tag(now);
print(fhq[now].l);
cout<<fhq[now].val<<' ';
print(fhq[now].r);
}
int main(){//显然,主函数
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)root=merge(root,newnode(i));
for(int i=1,a,b;i<=m;i++){
scanf("%d%d",&a,&b);
rev(a,b);
}
print(root);
return 0;
}
注意逝项#
- 输出过程中也要进行标记下放操作
- 标记下放很多,容易漏掉
- 大小分裂容易写错
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现