版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 2475

Splay树是一种神奇的东西。。。

题意:

  有一些箱子,要么放在地上,要么放在某个箱子里面 。

  现在有两种操作:

    (1) MOVE x y: 把 x 号箱子放到 y 号箱子里面,操作不合法就忽略这一次操作 。

    (2) QUERY x :  查询 x 号箱子最外面的箱子是哪一个

解法:

  首先对所有的树进行一遍DFS,得到一个DFS序,可以把它看成是一个括号序列,开始访问某个节点是左括号,结束访问时是右括号 。这样这题就转换成用Splay树来维护这个序列 。

  对于MOVE操作:

    将 x 对应那一段序列切下来,并将其放到 y 对应左括号的右边 。

  对于QUERY操作:

    直接查询以 x 为根的子树的最小值 。

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define ll long long using namespace std; const int N=; // 前向星
struct edge{
int to,nex;
}e[N];
int cnt;
int head[N]; inline void addedge(int u,int v){
e[cnt].to=v;
e[cnt].nex=head[u];
head[u]=cnt++;
} int id[N*]; // DFS序
int cou; int tot;
struct tree{
int key,fa,son[];
}t[N*];
int L[N],R[N]; // 第i个箱子所对应的左右括号在Splay树上的序号 inline void pushup(int x){}
inline void pushdown(int x){} inline void rotate(int x,int p){
int y=t[x].fa;
pushdown(y);
pushdown(x); t[y].son[!p]=t[x].son[p];
t[t[x].son[p]].fa=y;
t[x].fa=t[y].fa;
if (t[x].fa)
t[t[x].fa].son[t[t[x].fa].son[]==y]=x;
t[x].son[p]=y;
t[y].fa=x;
pushup(y);
pushup(x);
} inline void Splay(int x,int to){
while (t[x].fa!=to){
if (t[t[x].fa].fa==to)
rotate(x,t[t[x].fa].son[]==x);
else {
int y=t[x].fa, z=t[y].fa;
int p=(t[z].son[]==y);
if (t[y].son[p]==x)
rotate(x,!p),rotate(x,p);
else
rotate(y,p),rotate(x,p);
}
}
} inline int newnode(int key,int fa){
int x=tot++;
t[x].key=key;
t[x].fa=fa;
t[x].son[]=t[x].son[]=; if (key>) L[key]=x;
else R[-key]=x; return x;
} inline int get_min(int x){
while (t[x].son[]!=)
x=t[x].son[];
return x;
} inline int get_max(int x){
while (t[x].son[]!=)
x=t[x].son[];
return x;
} inline int bulid(int l,int r,int fa){
if (l>r) return ;
int x,mid=(l+r)>>;
x=newnode(id[mid],fa);
t[x].son[]=bulid(l,mid-,x);
t[x].son[]=bulid(mid+,r,x);
pushup(x);
return x;
} inline void dfs(int u){
id[cou++]=u;
for (int i=head[u];~i;i=e[i].nex)
dfs(e[i].to);
id[cou++]=-u;
} inline void init(){
memset(head,-,sizeof(head));
cnt=;
cou=;
tot=;
} inline int query(int a){
int x=L[a];
Splay(x,);
x=get_min(x);
return t[x].key;
} inline void move(int a,int b){
if (a==b) return; int x=L[a],y=R[a];
Splay(x,);
Splay(y,x); int xx=t[x].son[],yy=t[y].son[],z=;
z=get_max(xx); t[x].son[]=; t[y].son[]=;
t[xx].fa=; t[yy].fa=;
if (z!=) t[z].son[]=yy;
t[yy].fa=z; if (b==) return; if (query(b)==a){
t[x].son[]=xx; t[y].son[]=yy;
t[xx].fa=x; t[yy].fa=y;
t[z].son[]=;
return;
} int l=L[b],r;
Splay(l,);
r=get_min(t[l].son[]);
Splay(r,l);
t[r].son[]=x;
t[x].fa=r;
} int main(){
int n,q;
int x,y;
char ch[];
bool f=false;
while (scanf("%d",&n)!=EOF){
if (f) puts("");
else f=true; init(); for (int i=;i<=n;i++){
scanf("%d",&x);
addedge(x,i);
} dfs();
int k=,st=;
for (int i=;i<=*n;i++){
if (id[i]>) k++;
else k--;
if (k==) {
bulid(st,i,);
st=i+;
}
} scanf("%d",&q);
while (q--){
scanf("%s",ch);
if (ch[]=='Q') {
scanf("%d",&x);
printf("%d\n",query(x));
}
else {
scanf("%d %d",&x,&y);
move(x,y);
}
}
} return ;
}
 

hdu 2475 BOX (splay)的更多相关文章

  1. HDU 2475 BOX 动态树 Link-Cut Tree

    Box Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Problem De ...

  2. Box HDU - 2475 (Splay 维护森林)

    Box \[ Time Limit: 5000 ms \quad Memory Limit: 32768 kB \] 题意 给出 \(n\) 个箱子的包含关系,每次两种操作. 操作 \(1\):把 \ ...

  3. HDU 2475 Box

    Box Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 247564 ...

  4. HDU 2475 Box 树型转线型 + 伸展树

    树型转线型.第一次听说这个概念. . . , 可是曾经已经接触过了,如LCA的预处理部分和树链剖分等.可是没想到还能这么用,三者虽说有不同可是大体思想还是非常相近的,学习了. 推荐博客http://b ...

  5. HDOJ 题目2475 Box(link cut tree去点找祖先)

    Box Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  6. HDU - 2475:Box(splay维护森林)

    There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, th ...

  7. HDU 2088 Box of Bricks

    http://acm.hdu.edu.cn/showproblem.php?pid=2088 Problem Description Little Bob likes playing with his ...

  8. HDU 2088 Box of Bricks(脑洞)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2088 Box of Bricks Time Limit: 1000/1000 MS (Java/Oth ...

  9. 『嗨威说』算法设计与分析 - 贪心算法思想小结(HDU 2088 Box of Bricks)

    本文索引目录: 一.贪心算法的基本思想以及个人理解 二.汽车加油问题的贪心选择性质 三.一道贪心算法题点拨升华贪心思想 四.结对编程情况 一.贪心算法的基本思想以及个人理解: 1.1 基本概念: 首先 ...

随机推荐

  1. puthon进程开发

    进程 本节目录 一 背景知识 二 什么是进程 三 进程调度 四 并发与并行 五 同步\异步\阻塞\非阻塞 六 进程的创建与结束 七 multiprocess模块 八 进程池和mutiprocess.P ...

  2. 【入门向】使用 MetaHook Plus 绘制 HUD

    MetaHook Plus 是一个GoldSrc引擎(就是的Half-Life.CS1.6的引擎)的客户端插件平台,它可以加载我们自己开发的DLL插件. 首先你需要安装一个 Visual Studio ...

  3. C++解析(27):数组、智能指针与单例类模板

    0.目录 1.数组类模板 1.1 类模板高效率求和 1.2 数组类模板 1.3 堆数组类模板 2.智能指针类模板 2.1 使用智能指针 2.2 智能指针类模板 3.单例类模板 3.1 实现单例模式 3 ...

  4. [SCOI2016]幸运数字 线性基

    题面 题面 题解 题面意思非常明确:求树上一条链的最大异或和. 我们用倍增的思想. 将这条链分成2部分:x ---> lca , lca ---> y 分别求出这2个部分的线性基,然后合并 ...

  5. 【BZOJ5415】【NOI2018】归程(克鲁斯卡尔重构树)

    [NOI2018]归程(克鲁斯卡尔重构树) 题面 洛谷 题解 我在现场竟然没有把这道傻逼题给切掉,身败名裂. 因为这题就是克鲁斯卡尔重构树的模板题啊 我就直接简单的说一下把 首先发现答案就是在只经过海 ...

  6. RHEL 7中有关终端的快捷方式

    快速启动终端 网上有不错的教程,只是有时候和版本有一定的出入,这里涉及小白博主自行摸索的过程(RHEL 7.4). 1.点击桌面右上角,选择设置(小扳手) 2.选择键盘(Keyboard) 3.将进度 ...

  7. Linux集群--指定各个机器名字

    centOS7设置主机名:命令hostname可以查看当前主机名 虚招(临时的):重启机器后失效: hostname  XXX 实招(永久的): 招式一: 将/etc/sysconfig/networ ...

  8. fork系统炸弹

    最近偶然看到"fork系统炸弹"的代码,小小一行shell竟然能够直接搞死系统,令人印象深刻. 代码如下 :(){ :|:& };: 咋一看有点蒙,重新排版下格式 :() ...

  9. .Net并行编程系列之一:并行基础

    现在普通PC平台上面多核处理器的普及,让我们领教了能够利用多核进行并行计算的软件的处理能力,同时继承更多地核心正是当前处理器发展的趋势. 但是作为一个.NET开发人员,是否有时候会发现你的程序占用了其 ...

  10. RabbitMQ消息分发轮询和Message Acknowledgment

    一.消息分发 RabbitMQ中的消息都只能存储在Queue中,生产者(下图中的P)生产消息并最终投递到Queue中,消费者(下图中的C)可以从Queue中获取消息并消费. 多个消费者可以订阅同一个Q ...