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

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. (转载)Cobalt Strike tutorial下针对CVE-2017-0199利用

    CVE-2017-0199利用OLE对象嵌入Word / RTF文档的方式,使得可以在没有用户交互的情况下执行其内容.OLE由许多不同的程序支持,OLE通常用于使在另一个程序中可用的程序中创建的内容. ...

  2. Linux内核分析第二周--操作系统是如何工作的

    Linux内核分析第二周--操作系统是如何工作的 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...

  3. 谷哥的小弟学前端(02)——HTML常用标签(2)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...

  4. scala(三)

    一.面向对象编程——类 1.定义一个简单的类 class HelloWorld { private var name = "leo" def sayHello() { print( ...

  5. 简单的函数——Min_25筛

    %%yyb %%zsy 就是实现一下Min-25筛 筛积性函数的操作 首先要得到 $G(M,j)=\sum_{t=j}^{cnt} \sum_{e=1}^{p_t^{e+1}<=M} [\phi ...

  6. 【learning】矩阵树定理

    问题描述 给你一个图(有向无向都ok),求这个图的生成树个数 一些概念 度数矩阵:\(a[i][i]=degree[i]\),其他等于\(0\) 入度矩阵:\(a[i][i]=in\_degree[i ...

  7. Oracle中rank() over, dense_rank(), row_number() 的区别

    摘自:http://www.linuxidc.com/Linux/2015-04/116349.htm Oracle 中 rank() over, dense_rank(), row_number() ...

  8. FreeRTOSv9.0.0在STM32F103RCT6上的移植

    1.去官网下载源代码(FreeRTOSv9.0.0.exe) 2.取出Source文件夹,根据单片机和编译器不同,删除不需要的文件,如下图 3.在CORTEX_STM32F103_IAR文件夹中取出P ...

  9. 查看git拉取地址

    在项目地址下面输入:git remote -v 即可查看到地址啦.

  10. 「Python」python-nmap安装与入门

    1.安装namp https://nmap.org/download.html 下载链接 PS:windows安装似乎麻烦一些,需要多下载npcap,官网有链接 2.python安装 注意,注意,注意 ...