Hdu-3487 Splay树,删除,添加,Lazy延迟标记操作
HDU_3487
题意:给出n和q,n代表1-n的序列,接下来q有两种操作,Cut a b c:表示把区间[a,b]截掉然后放在第c个数的后面,Flip a b 表示把区间[a,b]反转,经过一系列的q操作,最后输出操作后的序列:
分析:首先建立初始化的树结构之前,先给n设置个极限范围0和n+1,防止特殊情况下越界,如果反转[a,b],则先把第a-1个数放在根节点,把b+1结点的数放在根节点的右儿子下面,此时根节点的右儿子的左儿子为根的子树就是[a,b]区间,然后把反转标记传递给该子树的根节点,如果剪切区间[a,b]则把第c+1个数旋转到根节点处,然后把根节点的右儿子为子树的最左面的节点旋转到该子树的根,此时把剪掉的子树的根节点连到根节点的右儿子的左儿子上面即可,需要注意的是,push_down和push_up的操作
codes:指针
- #include"stdio.h"
- #include"iostream"
- #include"queue"
- using namespace std;
- struct Link_cut
- {
- queue<int>q;
- struct node //节点结构体
- {
- int key,val,son,flag;
- node *lson,*rson,*fa; //左儿子,右儿子,以及父节点
- node()
- {
- key=val=flag=;
- son=;
- lson=rson=fa=NULL;
- }
- };
- node *top,*root,*x,*y;
- void init() //建立根节点root的父节点top
- {
- top=new node();
- }
- int getNum(node *x) //以x为根的子树一共有多少个节点
- {
- if(x==NULL)return ;
- return x->son;
- }
- void push_up(node *rt)
- {
- rt->son=getNum(rt->lson)+getNum(rt->rson)+;
- }
- void push_down(node *rt)
- {
- if(rt==NULL)return;
- if(rt->flag)
- {
- rt->flag^=;
- Reversal(rt);
- if(rt->lson!=NULL)
- rt->lson->flag^=;
- if(rt->rson!=NULL)
- rt->rson->flag^=;
- }
- }
- void Rotate(node *x,int k) //k=0左旋k=1右旋
- {
- node *y=x->fa;
- if(k==)
- {
- y->rson=x->lson;
- if(y->rson!=NULL)
- y->rson->fa=y;
- push_up(y);
- if(y->fa->rson==y)
- y->fa->rson=x;
- else
- y->fa->lson=x;
- x->fa=y->fa;
- x->lson=y;
- y->fa=x;
- }
- else
- {
- y->lson=x->rson;
- if(y->lson!=NULL)
- y->lson->fa=y;
- push_up(y);
- if(y->fa->lson==y)
- y->fa->lson=x;
- else
- y->fa->rson=x;
- x->fa=y->fa;
- x->rson=y;
- y->fa=x;
- }
- }
- void Splay(node *x,node *f)//把x旋转到f的下面
- {
- while(x->fa!=f)
- {
- node *y=x->fa;
- node *z=y->fa;
- if(z==f)
- {
- if(y->rson==x)
- Rotate(x,);
- else
- Rotate(x,);
- }
- else
- {
- if(z->rson==y)
- {
- if(y->rson==x)
- {
- Rotate(y,);
- Rotate(x,);
- }
- else
- {
- Rotate(x,);
- Rotate(x,);
- }
- }
- else
- {
- if(y->lson==x)
- {
- Rotate(y,);
- Rotate(x,);
- }
- else
- {
- Rotate(x,);
- Rotate(x,);
- }
- }
- }
- }
- if(f==top)
- root=x;
- }
- void RotateTo(node *x,node *f)
- {
- Splay(x,f);
- push_up(x);
- }
- void RotateTo(int k,node *f)
- {
- node *x=root;
- k++;
- while()
- {
- push_down(x);
- int temp=getNum(x->lson)+;
- if(k==temp)break;
- if(k<temp)
- x=x->lson;
- else
- {
- k-=temp;
- x=x->rson;
- }
- }
- Splay(x,f);
- push_up(x);
- }
- void creatTree(int l,int r,int k,node *f) //初始化一颗二叉树
- {
- if(l>r)return;
- int mid=(l+r)/;
- node *rt=new node();
- if(f==top)
- root=rt;
- if(k==)
- {
- f->lson=rt;
- rt->fa=f;
- rt->key=mid;
- }
- else
- {
- f->rson=rt;
- rt->fa=f;
- rt->key=mid;
- }
- creatTree(l,mid-,,rt);
- creatTree(mid+,r,,rt);
- push_up(rt);
- }
- void Reversal(node *x)//交换x左右儿子的结点
- {
- if(x==NULL)return;
- node *y=x->lson;
- x->lson=x->rson;
- x->rson=y;
- }
- node *Find(int k) //找到第k的结点
- {
- node *x=root;
- k++;
- while()
- {
- push_down(x);
- int temp=getNum(x->lson)+;
- if(k==temp)break;
- else if(k<temp)
- x=x->lson;
- else
- {
- k-=temp;
- x=x->rson;
- }
- }
- return x;
- }
- node *FindRight(node *rt) //找到以rt为根节点的最右一个结点
- {
- node *x=rt;
- while()
- {
- push_down(x);
- if(x->rson==NULL)
- break;
- x=x->rson;
- }
- return x;
- }
- node *FindLeft(node *rt) //找到以rt为根节点的最左一个结点
- {
- node *x=rt;
- while()
- {
- push_down(x);
- if(x->lson==NULL)break;
- x=x->lson;
- }
- return x;
- }
- void Link(node *rt,int k) //把rt为根的子树连接到第k个结点的后面
- {
- root->rson->lson=NULL; //把区间砍掉
- node *x=Find(k);
- RotateTo(x,top);
- node *y=FindLeft(root->rson);
- RotateTo(y,root);
- root->rson->lson=rt;
- rt->fa=root->rson;
- }
- void Output(node *x,int n)
- {
- if(x==NULL)return;
- push_down(x);
- Output(x->lson,n);
- if(x->key>=&&x->key<=n)
- q.push(x->key);
- Output(x->rson,n);
- }
- }h;
- int main()
- {
- int n,q;
- while(scanf("%d%d",&n,&q)!=-)
- {
- if(n==-&&q==-)break;
- h.init();
- h.creatTree(,n+,,h.top);
- char op[];
- int a,b,c;
- while(q--)
- {
- scanf("%s%d%d",op,&a,&b);
- if(op[]=='C')
- {
- scanf("%d",&c);
- h.RotateTo(a-,h.top);
- h.RotateTo(b+,h.root);
- h.Link(h.root->rson->lson,c);
- }
- else
- {
- h.RotateTo(a-,h.top);
- h.RotateTo(b+,h.root);
- h.root->rson->lson->flag^=;
- }
- }
- while(!h.q.empty())
- {
- h.q.pop();
- }
- h.Output(h.root,n);
- printf("%d",h.q.front());
- h.q.pop();
- while(!h.q.empty())
- {
- printf(" %d",h.q.front());
- h.q.pop();
- }
- puts("");
- }
- }
- /*
- 8 1
- CUT 3 5 4
- 5 1
- CUT 2 3 1
- 8 3
- Cut 3 6 3
- Cut 2 6 2
- Cut 3 6 4
- 8 1
- Flip 2 6
- 10 5
- Cut 2 6 3
- Flip 4 9
- Flip 5 8
- Cut 6 7 3
- Flip 4 5
- */
codes:数组模拟
- #include"stdio.h"
- #include"iostream"
- #include"queue"
- #include"string.h"
- #define M 3000005
- using namespace std;
- struct Text
- {
- int son[M][],fa[M],flip[M],num[M];
- int top;
- int root;
- vector<int>p;
- void init(int n)
- {
- top=n+;
- for(int i=;i<=n+;i++)
- {
- num[i]=;
- flip[i]=;
- son[i][]=son[i][]=-;
- fa[i]=-;
- }
- }
- void Rotate(int x,int k)
- {
- int y=fa[x];
- if(k==)
- {
- son[y][]=son[x][];
- if(son[y][]!=-)
- fa[son[y][]]=y;
- push_up(y);
- if(son[fa[y]][]==y)
- son[fa[y]][]=x;
- else
- son[fa[y]][]=x;
- fa[x]=fa[y];
- son[x][]=y;
- fa[y]=x;
- }
- else
- {
- son[y][]=son[x][];
- if(son[y][]!=-)
- fa[son[y][]]=y;
- push_up(y);
- if(son[fa[y]][]==y)
- son[fa[y]][]=x;
- else
- son[fa[y]][]=x;
- fa[x]=fa[y];
- son[x][]=y;
- fa[y]=x;
- }
- }
- int Find(int k)
- {
- k++;
- int x=root;
- while()
- {
- push_down(x);
- int temp=getNum(son[x][])+;
- if(temp==k)break;
- else if(k<temp)
- x=son[x][];
- else
- {
- k-=temp;
- x=son[x][];
- }
- }
- return x;
- }
- void splay(int x,int f)
- {
- if(x==-)return;
- while(fa[x]!=f)
- {
- int y=fa[x];
- int z=fa[y];
- if(z==f)
- {
- if(son[y][]==x)
- Rotate(x,);
- else
- Rotate(x,);
- }
- else
- {
- if(son[z][]==y)
- {
- if(son[y][]==x)
- {
- Rotate(y,);
- Rotate(x,);
- }
- else
- {
- Rotate(x,);
- Rotate(x,);
- }
- }
- else
- {
- if(son[y][]==x)
- {
- Rotate(y,);
- Rotate(x,);
- }
- else
- {
- Rotate(x,);
- Rotate(x,);
- }
- }
- }
- }
- if(f==top)
- root=x;
- }
- void RotateTo(int x,int f,int type)
- {
- if(!type)
- x=Find(x);
- splay(x,f);
- push_up(x);
- }
- void Reversal(int x)
- {
- if(x==-)return;
- int y=son[x][];
- son[x][]=son[x][];
- son[x][]=y;
- }
- void creat(int l,int r,int k,int f)
- {
- if(l>r)return;
- int mid=(l+r)/;
- if(f==top)
- root=mid;
- son[f][k]=mid;
- fa[mid]=f;
- creat(l,mid-,,mid);
- creat(mid+,r,,mid);
- push_up(mid);
- }
- int getNum(int x)
- {
- if(x==-)return ;
- return num[x];
- }
- void push_up(int rt)
- {
- num[rt]=getNum(son[rt][])+getNum(son[rt][])+;
- }
- void push_down(int rt)
- {
- if(rt==-)return;
- if(flip[rt])
- {
- flip[rt]^=;
- Reversal(rt);
- if(son[rt][]!=-)
- flip[son[rt][]]^=;
- if(son[rt][]!=-)
- flip[son[rt][]]^=;
- }
- }
- int findLeft(int rt)
- {
- int x=rt;
- while()
- {
- push_down(x);
- if(son[x][]==-)break;
- x=son[x][];
- }
- return x;
- }
- void CUT(int a,int b,int c)
- {
- RotateTo(a-,top,);
- RotateTo(b+,root,);
- int rt=son[son[root][]][];
- son[son[root][]][]=-;
- RotateTo(c,top,);
- int x=findLeft(son[root][]);
- RotateTo(x,root,);
- son[son[root][]][]=rt;
- fa[rt]=son[root][];
- }
- void FLIP(int a,int b)
- {
- RotateTo(a-,top,);
- RotateTo(b+,root,);
- int x=son[son[root][]][];
- flip[x]^=;
- }
- void dfs(int rt,int n)
- {
- if(rt==-)return;
- push_down(rt);
- dfs(son[rt][],n);
- if(rt>=&&rt<=n)
- p.push_back(rt);
- dfs(son[rt][],n);
- }
- void Output(int n)
- {
- dfs(root,n);
- printf("%d",p[]);
- for(int i=;i<(int)p.size();i++)
- printf(" %d",p[i]);
- puts("");
- p.clear();
- }
- }text;
- int main()
- {
- int n,q;
- while(scanf("%d%d",&n,&q)!=-)
- {
- if(n==q&&n==-)break;
- text.init(n);
- text.creat(,n+,,text.top);
- int a,b,c;
- char op[];
- while(q--)
- {
- scanf("%s%d%d",op,&a,&b);
- if(op[]=='C')
- {
- scanf("%d",&c);
- text.CUT(a,b,c);
- }
- else
- text.FLIP(a,b);
- }
- text.Output(n);
- }
- return ;
- }
- /*
- 10 5
- Cut 2 6 3
- Flip 4 9
- Flip 5 8
- Cut 6 7 3
- Flip 4 5
- 10 5
- Flip 4 9
- Flip 5 8
- Cut 6 7 3
- Flip 4 5
- 10 1
- Flip 2 9
- */
Hdu-3487 Splay树,删除,添加,Lazy延迟标记操作的更多相关文章
- hdu 3436 splay树+离散化*
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- HDU 3487 Splay
给定两种操作,一种是把一个数列的某一段切下来插到剩余数列的某一个位置上. 一种是翻转操作,把数列的某一段进行翻转. 都是Splay的基本操作.标准的Rotateto调整出 [a,b]区间.然后对[a, ...
- 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...
- hdu 1890 splay树
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- HDU 4391 Paint The Wall(分块+延迟标记)
Paint The Wall Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 题解报告:poj 3468 A Simple Problem with Integers(线段树区间修改+lazy懒标记or树状数组)
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- [线段树系列] LCT打延迟标记的正确姿势
这一篇博客将教你什么? 如何用LCT打延迟标记,LCT和线段树延迟标记间的关系,为什么延迟标记要这样打. ——正片开始—— 学习这一篇博客前,确保你会以下知识: Link-Cut-Tree,普通线段树 ...
- Chip Factory HDU - 5536 字典树(删除节点|增加节点)
题意: t组样例,对于每一组样例第一行输入一个n,下面在输入n个数 你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 ("^&qu ...
- HDU 3487 Splay tree
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
随机推荐
- asr,tts,vsr
http://max.book118.com/html/2014/0814/9432056.shtm ASR技术的基础主要是信号处理和概率模型. 信号处理技术 语音信号处理 谱分析 基于时间的 ...
- openssh-server 安装
sudo apt-get update sudo apt-get install openssh-server 1:ssh-keygen -t rsa -f ~/.ssh/id_rsa 这里会提示输入 ...
- ViewModel命令ICommand对象定义
如果定义如下 public ICommand ViewMenuItemCommand: 那么UI绑定,则无法执行代理方法 需如下定义 public ICommand ViewMenuItemComma ...
- 【转】Android的材料设计兼容库(Design Support Library)
转自:http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0531/2958.html?mType=Group Android的材料设计兼容 ...
- iOS工程如何支持64-bit
苹果在2014年10月20号发布了一条消息:从明年的二月一号开始,提交到App Store的应用必须支持64-bit.详细消息地址为:https://developer.apple.com/news/ ...
- php 或js 常用的正则表达式
1. 平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用:2. "^\d+$" //非负整数(正整数 + 0)3. "^[0-9 ...
- ps、grep和kill联合使用杀掉进程(转)
例如要杀掉hello这个进程,使用下面这个命令就能直接实现. ps -ef |grep hello |awk '{print $2}'|xargs kill -9 这里是输出ps -ef |gre ...
- shell脚本编程-使用结构化命令(if/else)(转)
11.1 使用if-then语句 格式如下 if语句会执行if行定义的那个命令,如果该命令的退出状态码是0,则then部分的语句就会执行,其他值,则不会 1 2 3 4 if command th ...
- Java之Ajax技术
ajax(asynchronouse javascript and xml) 异步的javascript 和 xml(现在常把xml换成json): ajax是2005年提出的,在2006,2007年 ...
- (copy) How to remote desktop a Fedora 19 from a Windows 7
source: http://forums.fedoraforum.org/showthread.php?t=293665 Try xrdp or freerdpInstall xrdp or fre ...