hdu 3487 区间翻转
来源:互联网 发布:打开8787端口 编辑:程序博客网 时间:2024/05/05 23:22
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define key_value ch[ch[root][1]][0]#define ls(r) ch[r][0]#define rs(r) ch[r][1]#define ll long longconst int N=300015;using namespace std;int n,q;int sz[N],pre[N],key[N],num[N],rev[N];int tot1,tot2;int root;int ch[N][2];int s[N];int cnt;//debugvoid treaval(int x){ if(x) { treaval(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d \n",x,ch[x][0],ch[x][1],pre[x],sz[x],key[x]); treaval(ch[x][1]); }}void debug(){ printf("%d\n",root);treaval(root);}void pushup(int r){ sz[r]=sz[ls(r)]+sz[rs(r)]+1;}void pushdown(int r){ if(rev[r]) { swap(ch[r][0],ch[r][1]); rev[ch[r][0]]^=1; rev[ch[r][1]]^=1; rev[r]=0; }}void newnode(int &r,int father, int k)//r必须是&{ if(tot2)r=s[tot2--];//取得时候tot2--,存++tot2 else r=++tot1; pre[r]=father; sz[r]=1; key[r]=k; rev[r]=0; ch[r][0]=ch[r][1]=0;}void build(int &x,int l,int r,int father){ if(l>r) return ; int mid=(l+r)/2; newnode(x,father,mid); build(ls(x),l,mid-1,x); build(rs(x),mid+1,r,x); pushup(x);}void init(){ tot1=tot2=0; sz[0]=0; //rev[0]=0; newnode(root,0,-1); newnode(rs(root),root,-1); build(key_value,1,n,rs(root)); pushup(rs(root)); pushup(root);}void rota(int x, int kind){ int y=pre[x]; pushdown(y); pushdown(x);//必须先把y的标记向下传递,在传x ch[y][!kind]=ch[x][kind],pre[ch[x][kind]]=y; if(pre[y])//??y的父节点不是root ch[pre[y]][ rs(pre[y])==y ]=x;//只能对这句牛逼的代码说声我屮艸芔茻 pre[x]=pre[y]; ch[x][kind]=y,pre[y]=x; pushup(y);//维护y结点 x节点的信息不用PushUp吗?可以证明这里除了y节点维护的信息不对外,其他所有点信息都正确 // pushup(x);//Push_Up(x);//这个可以不写,详见Crash:运用伸展树解决数列维护问题 论文,但是写了也不会多多少时间消耗}void Splay(int r, int goal)//将r调整到goal下面{ pushdown(r);// 离开之前把懒惰标记的信息传递 while(pre[r]!=goal) { if(pre[pre[r]]==goal) { //有反转操作,需要先pushdown; pushdown(pre[r]); pushdown(r); rota(r, ch[pre[r]][0]==r);//r在左子树,右旋 } else { //有反转操作,需要先pushdown; pushdown(pre[pre[r]]); pushdown(pre[r]); pushdown(r); int y=pre[r]; int kind=ch[pre[y]][0]==y; if(ch[y][kind]==r)//之字形旋转 {//y在其父节点的左子树上,r在y的右子树上 //或者y在其父节点的右子树,r在y左子树 rota(r, !kind); rota(r, kind); } else //一字型旋转 { rota(y, kind);//注意这里是y啊 rota(r, kind); } } } pushup(r); if(goal==0)root=r;}int getkth(int r, int k){ pushdown(r); int t=sz[ls(r)]+1; if(t==k)return r; if(t>k)return getkth(ls(r),k);//在左子树第k个 else return getkth(rs(r), k-t);//在右子树第k-t个}int get_min(int r){ pushdown(r); while(ch[r][0]) { r=ch[r][0]; pushdown(r); } return r;}void cut(int a,int b,int c){ int x=getkth(root,a); int y=getkth(root,b+2); Splay(x,0); Splay(y,root); int tmp=key_value; key_value=0; pushup(ch[root][1]); pushup(root); int z=getkth(root,c+1); Splay(z,0); int m=get_min(ch[root][1]); Splay(m,root); key_value=tmp; pre[key_value]=ch[root][1]; pushup(ch[root][1]); pushup(root);}void reversal(int a,int b){ int x=getkth(root,a); int y=getkth(root,b+2); Splay(x,0); Splay(y,root); rev[key_value]^=1;}void inorder(int r){ if(r==0) return ; pushdown(r); inorder(ls(r)); if(cnt>=1&&cnt<=n)//1-n cnt从0开始,排除最左最右点 { if(cnt>1) printf(" "); printf("%d",key[r]); } cnt++; inorder(rs(r));}int main(){ while(scanf("%d%d",&n,&q)!=EOF) { if(n==-1&&q==-1) break; init(); while(q--) { char str[10]; int a,b,c; scanf("%s",str); if(str[0]=='C') { scanf("%d%d%d",&a,&b,&c); cut(a,b,c); } else { scanf("%d%d",&a,&b); reversal(a,b); } } cnt=0; inorder(root); printf("\n"); }}
0 0
- hdu 3487 区间翻转
- hdu 3487 区间 翻转 切割 插入 splay
- HDU 3487 splay区间翻转切割
- hdu 1890 splay区间翻转
- HDU 1890 splay区间翻转
- HDU 1890 Splay区间翻转
- hdu 1890 splay 区间翻转
- hdu 1890 Splay区间最小值、区间翻转
- hdu 3487 Play with Chain splay 区间翻转,插入,删除
- Splay树(区间添加删除 | 区间翻转)——HDU 3487 Play with Chain
- hdu 1890 伸展树区间翻转
- HDU 1890 Robotic Sort (Splaytree 区间翻转)
- 【HDU】1890 Robotic Sort 翻转区间【splay】
- Hdu 1890 Robotic Sort(Spaly 区间翻转)
- HDU 1890 Robotic Sort(Splay 区间翻转)
- Hdu 3397 Sequence operation 区间合并+区间更新+翻转操作
- hdu 3487 Play with Chain (Splay树) 区间切割 插入 翻转
- hdu 1890 区间翻转——伸展树
- Linux shell脚本加密
- Android 4.4 Graphic系统详解(2) VSYNC的生成
- 权重
- 黑马程序员——IO流(二)
- 【笔记】JunitTest的Failure和Error
- hdu 3487 区间翻转
- 1048: [HAOI2007]分割矩阵——记忆化搜索
- Android 4.4 Graphic系统详解(3) 一个view的绘制之旅
- Mybatis3 缓存
- New Beginning
- 3-41(证明歌德巴猜想)
- Android 4.4 Graphic系统详解(4)HWUI概述
- 堆排序
- linux下如何添加一个用户并且让用户获得root权限