hdu 2475 BOX (splay)
版权声明:本文为博主原创文章,未经博主允许不得转载。
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)的更多相关文章
- HDU 2475 BOX 动态树 Link-Cut Tree
Box Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) [Problem De ...
- Box HDU - 2475 (Splay 维护森林)
Box \[ Time Limit: 5000 ms \quad Memory Limit: 32768 kB \] 题意 给出 \(n\) 个箱子的包含关系,每次两种操作. 操作 \(1\):把 \ ...
- HDU 2475 Box
Box Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 247564 ...
- HDU 2475 Box 树型转线型 + 伸展树
树型转线型.第一次听说这个概念. . . , 可是曾经已经接触过了,如LCA的预处理部分和树链剖分等.可是没想到还能这么用,三者虽说有不同可是大体思想还是非常相近的,学习了. 推荐博客http://b ...
- HDOJ 题目2475 Box(link cut tree去点找祖先)
Box Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 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 ...
- HDU 2088 Box of Bricks
http://acm.hdu.edu.cn/showproblem.php?pid=2088 Problem Description Little Bob likes playing with his ...
- HDU 2088 Box of Bricks(脑洞)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2088 Box of Bricks Time Limit: 1000/1000 MS (Java/Oth ...
- 『嗨威说』算法设计与分析 - 贪心算法思想小结(HDU 2088 Box of Bricks)
本文索引目录: 一.贪心算法的基本思想以及个人理解 二.汽车加油问题的贪心选择性质 三.一道贪心算法题点拨升华贪心思想 四.结对编程情况 一.贪心算法的基本思想以及个人理解: 1.1 基本概念: 首先 ...
随机推荐
- 【bzoj5099】[POI2018]Pionek 双指针法
题目描述 给你 $n$ 个平面向量,选出它们中的一部分,使得它们的和的长度最大.求这个最大长度的平方. 输入 第一行包含一个正整数n(n<=200000),表示指令条数. 接下来n行,每行两个整 ...
- BZOJ3551 ONTAK2010Peaks加强版(kruskal重构树+dfs序+主席树)
kruskal重构树本质就是给并查集显式建树来替代可持久化并查集.将边按困难度从小到大排序后建出该树,按dfs序建主席树即可.查询时跳到深度最浅的满足在该重要度下已被合并的点,在子树内查询第k大. # ...
- 深入理解JVM一垃圾回收算法
我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理. 一.stop the world 在介绍 ...
- PD模型创建完获取生成表脚本
1.双击表名,弹出属性对话框-->General----> Owner 表名前缀,如XX.SYS_TABLE 最好去掉 2.Preview 复制里面的脚本到数据库执行下即可
- 【HDU4336】Card Collector (动态规划,数学期望)
[HDU4336]Card Collector (动态规划,数学期望) 题面 Vjudge 题解 设\(f[i]\)表示状态\(i\)到达目标状态的期望 \(f[i]=(\sum f[j]*p[j]+ ...
- 【bzoj2588】Count on a tree
Portal -->bzoj2588 Solution 不行我一定要来挂这道题qwq很气愤qwq(其实还不是因为自己蠢..) 额首先说一下正解 如果这个问题放在序列上面的话..直接离散化一下然后 ...
- 前端基础----html初识、常用标签
一.HTML初识 web服务本质 import socket def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ...
- 【hash】【P5079】P5079 Tweetuzki 爱伊图
Description Input 第一行两个正整数 \(r~,~c\),表示矩阵的行数和列数. 接下来 \(r\) 行,每行输入 \(c\) 个字符,用空格隔开,保证只含有 . 和 # 两种字符.输 ...
- JSTL获取当日时间与数据时间比较
<jsp:useBean id="now" class="java.util.Date" /> <fmt:formatDate value=& ...
- 用trigger触发datepicker
jQuery UI的datepicker没有icon图片,工作需要,自己写了一个,原理是用div包裹住datepicker的input和一个button,隐藏掉input,而button被点击后也可以 ...