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延迟标记操作的更多相关文章

  1. hdu 3436 splay树+离散化*

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  2. HDU 3487 Splay

    给定两种操作,一种是把一个数列的某一段切下来插到剩余数列的某一个位置上. 一种是翻转操作,把数列的某一段进行翻转. 都是Splay的基本操作.标准的Rotateto调整出 [a,b]区间.然后对[a, ...

  3. 题解报告: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 ...

  4. hdu 1890 splay树

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  5. HDU 4391 Paint The Wall(分块+延迟标记)

    Paint The Wall Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. 题解报告: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 ...

  7. [线段树系列] LCT打延迟标记的正确姿势

    这一篇博客将教你什么? 如何用LCT打延迟标记,LCT和线段树延迟标记间的关系,为什么延迟标记要这样打. ——正片开始—— 学习这一篇博客前,确保你会以下知识: Link-Cut-Tree,普通线段树 ...

  8. Chip Factory HDU - 5536 字典树(删除节点|增加节点)

    题意: t组样例,对于每一组样例第一行输入一个n,下面在输入n个数 你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 ("^&qu ...

  9. HDU 3487 Splay tree

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

随机推荐

  1. prior knowledge

    https://en.wikipedia.org/wiki/Bayes'_theorem For example, if cancer is related to age, then, using B ...

  2. What's Assembly - CSharp - Editor - first pass.dll? Best How to Fix Assembly - CSharp - Editor - first pass.dll Error Guide

    If you've found yourself here, I'm guessing that you're getting Assembly - CSharp - Editor - first p ...

  3. App Previews操作经验

    App Previews操作经验 http://www.cocoachina.com/ios/20140924/9741.html http://www.cocoachina.com/bbs/read ...

  4. error: jump to label ‘XXXX’ [-fpermissive]

    http://www.cnblogs.com/foohack/p/4090124.html 下面的类似的源码在MSVC上能正确编译通过.但是gcc/g++上就会错: 1. if(expr)2. got ...

  5. docker debug diagnose

    $ sudo systemctl stop docker $ sudo docker -d -D DEBU[0282] Error contacting registry https://regist ...

  6. 关于hive的存储格式

    1.存储格式 textfile rcfile orc parquet 2.存储方式 按行存储 ->textfile 按列存储 ->parquet 3.压缩比 4.存储textfile的原文 ...

  7. 其他常用HTML 片段

    1.input placeholder 文字居中 字体大小+上下padding值等于设计稿宽度 设计稿中总高度为86px   padding:27px 0;font-size:30px;   2.英文 ...

  8. Spark Programming--WordCount

    首先在$SPARK_HOME主目录下建立一个test文件夹,里面放一些文件(注意文件全部内容都可被hadoop用户访问,否则运行会出现permission denied的错误) 打开pyspark: ...

  9. 关于lnmp下搭thinkPHP无法找到指定静态页面

    我在lnmp 下架了一个thinkPHP框架,非常奇怪,在环境都配置好后,我在url里输入localhost:10007/index.php/member/login,正常来说应该显示login.ht ...

  10. maven小记

    编译webx3.0,必须用maven 3.0 git clone https://github.com/webx/citrus.gitmaven clean install -DskipTest(Te ...