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 基本概念: 首先 ...
随机推荐
- MySQL join 使用方法
JOIN 按照功能大致分为如下三类: INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录. LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(tab ...
- 【Java】判断字符串是否包含子字符串
JAVA里面判断: public static void main(String[] args) { String str="ABC_001"; if(str.indexOf(&q ...
- Day20-单表中获取表单数据的3种方式
1. 搭建环境请参考:http://www.cnblogs.com/momo8238/p/7508677.html 2. 创建表结构 models.py from django.db import m ...
- 转:Python 文本挖掘:使用gensim进行文本相似度计算
Python使用gensim进行文本相似度计算 转于:http://rzcoding.blog.163.com/blog/static/2222810172013101895642665/ 在文本处理 ...
- 【转】WinForms 使用Graphics绘制字体阴影
转自:http://www.cnblogs.com/LonelyShadow/p/3893743.html C#以两种方法实现文字阴影效果,同时还实现了简单的动画效果: 一种是对文本使用去锯齿的边缘处 ...
- 基于数组实现Java 自定义Stack栈类及应用
栈是存放对象的一种特殊容器,在插入与删除对象时,这种结构遵循后进先出( Last-in-first-out,LIFO)的原则.java本身是有自带Stack类包,为了达到学习目的已经更好深入了解sta ...
- 解题:HNOI 2008 玩具装箱
题面 搞了一晚上斜率优化,大概懂了一点,写写 原来常用的优化dp方法:做前缀和,预处理,数据结构维护 现在有转移方程长这样的一类dp:$dp[i]=min(dp[i],k[i]*x[j]+y[j]+c ...
- mybatis sql使用经验总结
1.where 后面如果有动态sql,可以添加一个1=1条件,然后在后面添加动态sql语句,里面添加AND 例如: <select id="queryBizMonitorHistory ...
- [DeeplearningAI笔记]序列模型3.2有条件的语言模型与贪心搜索的不可行性
5.3序列模型与注意力机制 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.2选择最可能的句子 Picking the most likely sentence condition lan ...
- CDN问题积累
我见到的CDN服务器只支持GET方法,只能以URL为索引来缓存内容. 有的时候我用相同的URL,相同的GET方法,但是不同Header参数时,后台对应的应该是不同的方法,返回不同的结果. 而这时候使用 ...