CODEVS 3243 区间翻转 (SBT)
来源:互联网 发布:深圳知创科技有限公司 编辑:程序博客网 时间:2024/06/05 05:10
SBT实现区间翻转:
框架还是SBT的框架,加个翻转标记,旋转时记得维护标记,加个函数,把某棵树的根设置为树中第k大的数。
然后翻转区间L,R 就是把根转成R+1,再把左子树转成L-1,然后根的左子树的右子树就是所要翻转的区间,给它加个翻转标记就解决了。
为了能够翻转从1开始的区间,和到n的区间,在树的最前和最后各加了一个无用的元素。
每次翻转之后平衡一次的话,效率会降低,所以就省去了平衡函数。
在CODEVS上测得总耗时 755ms 。
/*作者:Zearot题目:p3243 区间翻转*/#include<cstdio>#include<iostream>#include<cstring>#define maxn 150007using namespace std; int L[maxn],R[maxn],S[maxn],K[maxn],IP;//Left,Right,Size,Key,指针 bool Turn[maxn];//翻转标记,被标记的点未翻转 int ANS[maxn],ANSIP;void PushDown(int rt){if(Turn[rt]){Turn[L[rt]]^=1;Turn[R[rt]]^=1;swap(L[rt],R[rt]);Turn[rt]=0;}}void zig(int &rt){PushDown(rt);PushDown(R[rt]);int t=R[rt];R[rt]=L[t];L[t]=rt;S[t]=S[rt];S[rt]=1+S[L[rt]]+S[R[rt]];rt=t; }void zag(int &rt){PushDown(rt);PushDown(L[rt]);int t=L[rt];L[rt]=R[t];R[t]=rt;S[t]=S[rt];S[rt]=1+S[L[rt]]+S[R[rt]];rt=t;}int n,m;void Build(int &rt,int A,int B){//K下标为0到n+1的数据建树 int M=(A+B)>>1;rt=++IP;L[rt]=R[rt]=0;S[rt]=B-A+1;K[rt]=ANS[M];if(A < M) Build(L[rt],A,M-1);if(B > M) Build(R[rt],M+1,B);}void Show(int &rt){PushDown(rt);if(L[rt]) Show(L[rt]);ANS[ANSIP++]=K[rt];if(R[rt]) Show(R[rt]);}void SetRootTo(int &rt,int k){//改成非递归的话,效率可以提高 PushDown(rt);if(S[L[rt]]+1==k) return;if(S[L[rt]]>=k){SetRootTo(L[rt],k);zag(rt);return;}else {SetRootTo(R[rt],k-S[L[rt]]-1);zig(rt);return;}}void Reverse(int &rt,int Left,int Right){SetRootTo(rt,Right+2);SetRootTo(L[rt],Left);Turn[R[L[rt]]]^=1;}int main(void){scanf("%d",&n);for(int i=1;i<=n;++i) scanf("%d",&ANS[i]);int rt=0;IP=0;Build(rt,0,n+1);scanf("%d",&m);for(int i=0;i<m;++i){ int Left,Right;scanf("%d%d",&Left,&Right); //翻转操作 Reverse(rt,Left,Right); } ANSIP=0; Show(rt); for(int i=1;i<=n;++i){ printf("%d",ANS[i]); if(i==n) printf("\n"); else printf(" "); } return 0;}
0 0
- CODEVS 3243 区间翻转 (SBT)
- CODEVS 1743(伸展树区间翻转)
- CODEVS-3303-翻转区间
- 【CodeVS】3303 翻转区间
- 【codevs 3303】翻转区间 splay
- codevs 1743 反转卡片【Splay区间翻转】
- 【codevs 3243】区间反转(线段树)
- codevs 1258(区间dp)
- HDU3487(splay区间翻转+区间切割)
- codevs 1743 翻转卡片(splay)
- codevs 1205单词翻转(stl运用)
- 【CODEVS 1154】能量项链(区间DP)
- codevs 1048能量项链(区间DP)
- CODEVS 1205 单词翻转
- codevs 1205 单词翻转
- Codevs 1205 单词翻转
- codevs 1205单词翻转
- CodeVS 1082 (区间修改+区间查询树状数组模板)
- AddTwoNumbers
- Reactor设计模式基础知识
- 【COGS257】动态排名系统
- Convert Sorted Array to Binary Search Tree
- poj 3128 Leonardo's Notebook (置换群)
- CODEVS 3243 区间翻转 (SBT)
- 常见向量范数和矩阵范数
- [XML] SAX解析
- 守护进程的设计与实现
- mvc架构模式与视图控制器
- 基于JZ2440的按键控制GPIO灯的亮灭
- junit4学习笔记
- 飞机大战开发02之添加玩家飞机
- 第31课时,实践,画循环流程图