链接

推荐一篇帖子

http://blog.csdn.net/lyhypacm/article/details/6734748

这题暴力不可行主要是因为这颗树可能极度不平衡,不能用并查集是不能路径压缩,这样时间复杂度是很高的。

可以用伸展树主要是因为它的伸展性,每次操作后可以通过伸展使这棵树更好的保持平衡。

这题还是值得记录一下的,从早上做到了晚上,

第一次错误,定义了全局的n以及局部的n使得取得结果不正确,以后还是统一习惯,要么写在全局要么写在局部。

第二次错误,vector初始化没有初始到0导致后面的数据跑不动,以后初始化的操作都从0开始。

第三次错误,debug了n久,建树的时候误把根节点的父亲节点写成了根,应该是0,自以为不会出错的地方也要认真检查。

 #include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
using namespace std;
#define N 100010
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
int n,po[N];
vector<int>ed[N];
vector<int>dd; struct splay_tree
{
int pre[N];
int ch[N][];
int root,tot,num;
int key[N];
// void dfs(int x)
// {
// if(x)
// {
// dfs(ch[x][0]);
// printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d\n",
// x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
// dfs(ch[x][1]);
// }
// }
// void debug()
// {
// printf("root:%d\n",root);
// dfs(root);
// }
//以上用于debug*/
void newnode(int &x,int v,int fa)//新建一结点
{
x = ++tot;
ch[x][]=ch[x][] = ;
pre[x] = fa;
key[x] = v;
po[v] = x;
}
void pushup(int w)//由儿子更新其父亲
{
}
void rotate(int r,int kind)//旋转操作,根据kind进行左旋和右旋
{
int y = pre[r];
ch[y][!kind] = ch[r][kind];
pre[ch[r][kind]] = y;
if(pre[y])
{
ch[pre[y]][ch[pre[y]][]==y] = r;
}
pre[r] = pre[y];
ch[r][kind] = y;
pre[y] = r;
pushup(y);
pushup(r);
}
void splay(int r,int goal)//将r结点旋至goal下
{
while(pre[r]!=goal)
{
if(pre[pre[r]]==goal)
{
rotate(r,ch[pre[r]][]==r);
}
else
{
int y = pre[r];
int kind = (ch[pre[y]][]==y);
if(ch[y][kind]==r)
{
rotate(r,!kind);
rotate(r,kind);
}
else
{
rotate(y,kind);
rotate(r,kind);
}
}
}
pushup(r);
if(goal==) root = r;
}
int get_min(int x)
{
while(ch[x][])
x = ch[x][];
return x;
}
int get_max(int x)
{
while(ch[x][])
x = ch[x][];
return x;
}
void update(int x,int y) //更新区间信息
{
int l = po[x],r = po[x+n];
splay(l,);
splay(r,);
int ll = ch[l][];
int rr = ch[r][];
pre[ll] = pre[rr] = ;
ch[r][] = ch[l][] = ; int tll = get_max(ll);
if(tll!=)
ch[tll][] = rr;
pre[rr] = tll; if(y==) return ;
if(query(y)==x)
{
ch[r][] = rr;
ch[l][] = ll;
pre[ll] = l;
pre[rr] = r;
ch[tll][] = ;
pre[] = ;
return ;
} if(rr!=) splay(rr,);
int tt = po[y];
splay(tt,);
int tq = get_min(ch[tt][]);
splay(tq,tt);
ch[tq][] = r;
pre[r] = tq;
}
int query(int x)//询问l,r区间,将第l-1个结点旋自根,第r+1个结点旋自根的有儿子,
{
splay(po[x],);
int k = get_min(po[x]);
return key[k];
}
void build(int &x,int l,int r,int fa)
{
int m = (l+r)>>;
if(l>r) return ;
newnode(x,dd[m],fa);
build(ch[x][],l,m-,x);
build(ch[x][],m+,r,x);
pushup(x);
}
void init()
{
root = tot = ;
memset(ch,,sizeof(ch));
memset(pre,,sizeof(pre));
memset(key,,sizeof(key));
memset(po,,sizeof(po));
}
} SP;
void dfs(int u)
{
int i;
dd.push_back(u);
for(i = ; i < ed[u].size(); i++)
{
int v = ed[u][i];
dfs(v);
}
dd.push_back(u+n);
}
int main()
{
int i;
int q;
int mark = false;
while(scanf("%d",&n)!=EOF)
{
if(mark)
puts("");
else
mark = true;
SP.init();
for(i = ; i <= n; i++)
{
ed[i].clear();
}
dd.clear();
for(i = ; i <= n; i++)
{
int x;
scanf("%d",&x);
ed[x].push_back(i);
}
dfs();
int o = ;
scanf("%d",&q);
stack<int>st;
for(i = ; i < dd.size()- ; i++)
{
int x = dd[i];
if(x<=n) st.push(x);
else st.pop();
if(st.empty())
{
SP.build(SP.root,o,i,);
o = i+;
}
}
int stt = ;
while(q--)
{
char sq[];
int x,y;
scanf("%s",sq);
if(sq[]=='Q')
{
scanf("%d",&x);
printf("%d\n",SP.query(x));
}
else
{
scanf("%d%d",&x,&y);
SP.update(x,y);
}
}
}
return ;
}

hdu2475Box(splay树形转线性)的更多相关文章

  1. Codeforces 570D - Tree Requests【树形转线性,前缀和】

    http://codeforces.com/contest/570/problem/D 给一棵有根树(50w个点)(指定根是1号节点),每个点上有一个小写字母,然后有最多50w个询问,每个询问给出x和 ...

  2. CodeForces 466E Information Graph --树形转线性+并查集

    题意:有三种操作: 1.新增一条边从y连向x,此前x没有父节点 2.x接到一份文件,(文件标号逐次递增),然后将这份文件一路上溯,让所有上溯的节点都接到这份文件 3.查询某个节点x是否接到过文件F 解 ...

  3. 线性结构与树形结构相互转换(ES6实现)

    前言 当树形结构的层级越来越深时,操作某一节点会变得越来越费劲,维护成本不断增加.所以线性结构与树形的相互转换变得异常重要! 首先,我们约定树形结构如下: node = { id: number, / ...

  4. 第一阶段:Java内功秘籍-线性表

    前言 为什么要学习数据结构与算法,如果你学会了做安卓,javaweb,前端等,都是你的武功秘籍,但是如果你的内功不够好,再厉害的功夫也是白费. 数据结构和算法:什么是数据结构,什么是数据,在计算机内部 ...

  5. RMQ 与 LCA-ST算法

    RMQ算法 区间求最值的算法,用区间动态规划(nlogn)预处理,查询O(1) http://blog.csdn.net/y990041769/article/details/38405063 (PO ...

  6. 树链剖分详解(洛谷模板 P3384)

    洛谷·[模板]树链剖分 写在前面 首先,在学树链剖分之前最好先把 LCA.树形DP.DFS序 这三个知识点学了 emm还有必备的 链式前向星.线段树 也要先学了. 如果这三个知识点没掌握好的话,树链剖 ...

  7. Kuangbin 带你飞-线段树专题 题解

    HDU 1166 敌兵布阵 单调更新区间查询和 #include <map> #include <set> #include <list> #include < ...

  8. git使用笔记-基础篇

    git使用手册:https://git-scm.com/book/zh/v1/ 一.分支 1.查看所有本地分支 git branch 2.查看所有本地分支和远程分支 git branch -a 3.查 ...

  9. UVA10410 TreeReconstruction 树重建 (dfs,bfs序的一些性质,以及用栈处理递归 )

    题意,给你一颗树的bfs序和dfs序,结点编号小的优先历遍,问你可能的一种树形: 输出每个结点的子结点. 注意到以下事实: (1)dfs序中一个结点的子树结点一定是连续的. (2)bfs,dfs序中的 ...

随机推荐

  1. 万亿级日志与行为数据存储查询技术剖析——Hbase系预聚合方案、Dremel系parquet列存储、预聚合系、Lucene系

    转自:http://www.infoq.com/cn/articles/trillion-log-and-data-storage-query-techniques?utm_source=infoq& ...

  2. 字面量(literal)与 C 语言复合字面量(compound literals)

    在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(notation)(字面量是相对变量常量等定义的,无论是常量还是变量,其值在某一时刻总是确定的,只是变量可以反复赋值.刷新 ...

  3. eslintrc.js

    此插件主要就是规范前端程序员编写JS的规范,让代码看上去很优雅,也便于后期人员的重构和维护. 因为是用vue的cli搭建项目工程,使用了eslintrc.js ,但是在写JS时发现,首字母缩进一直报错 ...

  4. tcp连接时,BROKEN PIPE错误的原因以及解决方法

    问题: 写了一个server和一个client,UNIX套接字的,server不断接收消息并打印出来,client是一个交互程序,输入一个消息回车发送,接着又可以输入消息.出问题了:当server监听 ...

  5. android项目源码

    [置顶] Android精品开源项目整理_V20140221(持续更新中..) 让我们回顾下2013年有哪些精品资源:Android精品开源项目整理_V20131115(持续更新中..) 引言:   ...

  6. Unity3D 开发ios时困扰多时游戏开始画面图片的分辨率

  7. 单例模式-Lazy initialization holder class模式

    这个模式综合使用了Java的类级内部类和多线程缺省同步锁的知识,很巧妙地同时实现了延迟加载和线程安全. 1.相应的基础知识 什么是类级内部类? 简单点说,类级内部类指的是,有static修饰的成员式内 ...

  8. django继承修改 User表导致的问题 fields.E304(permissions/group都会有这样的错误)

    问题: django继承修改 User表时,进行migrations操作时会导致的问题 fields.E304(permissions/group都会有这样的错误)如图: 根源: django文档中有 ...

  9. django使用QQ企业邮箱发送邮件

    一.首先申请QQ企业邮箱 免费QQ企业邮箱地址如下:https://exmail.qq.com/signupfree?refer=intro#signup/free 二.配置自己的域名 在域名解析中添 ...

  10. Unity3D调用摄像头,画面为翻转的问题

    http://blog.csdn.net/a117653909/article/details/16119907 Unity3D中新建一个工程,加一个Plane,新建一个C# 脚本,调用摄像头,不过显 ...