BZOJ4825 [Hnoi2017]单旋 【线段树】
题目链接
题解
手模一下操作,会发现一些很优美的性质:
每次旋到根,只有其子树深度不变,剩余点深度\(+1\)
每次旋到根,【最小值为例】右儿子接到其父亲的左儿子,其余点形态不改变,然后将该点接到根之上,原根变为其右儿子
每次插入,都是插入到其前驱后继深度较大的那一个点之下
所以我们很容易模拟出树的形态,同时用线段树维护离散化后各权值的深度
#include<iostream>
#include<cstdio>
#include<cmath>
#include<set>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
set<int> S;
struct Que{
int opt,v;
}Q[maxn];
int fa[maxn],ls[maxn],rs[maxn];
int b[maxn],tot,m;
int getn(int x){return lower_bound(b + 1,b + 1 + tot,x) - b;}
int val[maxn << 2],tag[maxn << 2];
void pd(int u){
if (tag[u]){
val[u << 1] += tag[u]; tag[u << 1] += tag[u];
val[u << 1 | 1] += tag[u]; tag[u << 1 | 1] += tag[u];
tag[u] = 0;
}
}
void change(int u,int l,int r,int pos,int v){
if (l == r) {val[u] = v; return;}
pd(u);
int mid = l + r >> 1;
if (mid >= pos) change(u << 1,l,mid,pos,v);
else change(u << 1 | 1,mid + 1,r,pos,v);
}
void modify(int u,int l,int r,int L,int R,int v){
if (l >= L && r <= R) {val[u] += v; tag[u] += v; return;}
pd(u);
int mid = l + r >> 1;
if (mid >= L) modify(u << 1,l,mid,L,R,v);
if (mid < R) modify(u << 1 | 1,mid + 1,r,L,R,v);
}
int query(int u,int l,int r,int pos){
if (l == r) return val[u];
pd(u);
int mid = l + r >> 1;
if (mid >= pos) return query(u << 1,l,mid,pos);
return query(u << 1 | 1,mid + 1,r,pos);
}
void print(int u,int l,int r){
if (l == r) printf("%d ",val[u]);
else {
pd(u);
int mid = l + r >> 1;
print(u << 1,l,mid);
print(u << 1 | 1,mid + 1,r);
}
}
int main(){
m = read(); int n = 0;
REP(i,m){
Q[i].opt = read();
if (Q[i].opt == 1) b[++n] = Q[i].v = read();
}
sort(b + 1,b + 1 + n); tot = 1;
for (int i = 2; i <= n; i++) if (b[i] != b[tot]) b[++tot] = b[i];
S.insert(0); S.insert(tot + 10);
int pre,nxt,d1,d2,u,v,rt;
for (int i = 1; i <= m; i++){
if (Q[i].opt == 1){
u = getn(Q[i].v);
S.insert(u);
pre = *--S.find(u);
nxt = *++S.find(u);
if (pre == 0 && nxt == tot + 10)
change(1,1,tot,u,1),rt = u;
else if (pre == 0){
d1 = query(1,1,tot,nxt);
change(1,1,tot,u,d1 + 1);
fa[u] = nxt; ls[nxt] = u;
}
else if (nxt == tot + 10){
d2 = query(1,1,tot,pre);
change(1,1,tot,u,d2 + 1);
fa[u] = pre; rs[pre] = u;
}
else {
d1 = query(1,1,tot,nxt);
d2 = query(1,1,tot,pre);
if (d1 > d2){
change(1,1,tot,u,d1 + 1);
fa[u] = nxt; ls[nxt] = u;
}
else {
change(1,1,tot,u,d2 + 1);
fa[u] = pre; rs[pre] = u;
}
}
ls[u] = rs[u] = 0;
printf("%d\n",query(1,1,tot,u));
}
else if (Q[i].opt == 2){
u = *++S.find(0);
printf("%d\n",query(1,1,tot,u));
if (!fa[u]) continue;
modify(1,1,tot,fa[u],tot,1);
change(1,1,tot,u,1);
v = fa[u];
ls[v] = rs[u]; if (rs[u]) fa[rs[u]] = v;
rs[u] = rt; fa[rt] = u; fa[u] = 0;
rt = u;
}
else if (Q[i].opt == 3){
u = *--S.find(tot + 10);
printf("%d\n",query(1,1,tot,u));
if (!fa[u]) continue;
modify(1,1,tot,1,fa[u],1);
change(1,1,tot,u,1);
v = fa[u];
rs[v] = ls[u]; if (ls[u]) fa[ls[u]] = v;
ls[u] = rt; fa[rt] = u; fa[u] = 0;
rt = u;
}
else if (Q[i].opt == 4){
u = *++S.find(0);
printf("%d\n",query(1,1,tot,u));
if (fa[u]) modify(1,1,tot,u,fa[u] - 1,-1);
else modify(1,1,tot,1,tot,-1);
if (v = fa[u]){
ls[v] = rs[u]; if (rs[u]) fa[rs[u]] = v;
rs[u] = 0;
}
else if (rs[u]) fa[rs[u]] = 0,rt = rs[u],rs[u] = 0;
S.erase(u);
}
else if (Q[i].opt == 5){
u = *--S.find(tot + 10);
printf("%d\n",query(1,1,tot,u));
if (fa[u]) modify(1,1,tot,fa[u] + 1,u,-1);
else modify(1,1,tot,1,tot,-1);
if (v = fa[u]){
rs[v] = ls[u]; if (ls[u]) fa[ls[u]] = v;
ls[u] = 0;
}
else if (ls[u]) fa[ls[u]] = 0,rt = ls[u],ls[u] = 0;
S.erase(u);
}
/*printf("rt = %d\n",b[rt]);
for (int i = 1; i <= tot; i++){
printf("node%d fa = %d ,ls = %d rs = %d\n",b[i],b[fa[i]],b[ls[i]],b[rs[i]]);
}
print(1,1,tot); puts("");*/
}
return 0;
}
BZOJ4825 [Hnoi2017]单旋 【线段树】的更多相关文章
- [BZOJ4825][HNOI2017]单旋(线段树+Splay)
4825: [Hnoi2017]单旋 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 667 Solved: 342[Submit][Status][ ...
- 【BZOJ4825】[Hnoi2017]单旋 线段树+set
[BZOJ4825][Hnoi2017]单旋 Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能 ...
- 【bzoj4825】[Hnoi2017]单旋 线段树+STL-set
题目描述 H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必修技能.有一天 ...
- BZOJ.4825.[AHOI/HNOI2017]单旋(线段树)
BZOJ LOJ 洛谷 这题不难啊,我怎么就那么傻,拿随便一个节点去模拟.. 我们只需要能够维护,将最小值或最大值转到根.模拟一下发现,对于最小值,它的右子树深度不变(如果存在),其余节点深度全部\( ...
- 洛谷P3721 [AH2017/HNOI2017]单旋(线段树 set spaly)
题意 题目链接 Sol 这题好毒瘤啊.. 首先要观察到几个性质: 将最小值旋转到根相当于把右子树变为祖先的左子树,然后将原来的根变为当前最小值 上述操作对深度的影响相当于右子树不变,其他的位置-1 然 ...
- bzoj4825 [Hnoi2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...
- BZOJ4825: [Hnoi2017]单旋(Splay)
题面 传送门 题解 调了好几个小时--指针太难写了-- 因为只单旋最值,我们以单旋\(\min\)为例,那么\(\min\)是没有左子树的,而它旋到根之后,它的深度变为\(1\),它的右子树里所有节点 ...
- [BZOJ4825][HNOI2017]单旋spaly
BZOJ Luogu 题目太长了,就不放了. 题解 首先声明一点,无论是splay还是spaly,插入一个新的元素,都要rotate到根!所以说题目也算是给了一个错误示范吧. 我们发现把最值旋转到根并 ...
- 4825: [Hnoi2017]单旋
4825: [Hnoi2017]单旋 链接 分析: 以后采取更保险的方式写代码!!!81行本来以为不特判也可以,然后就总是比答案大1,甚至出现负数,调啊调啊调啊调~~~ 只会旋转最大值和最小值,以最小 ...
随机推荐
- 关于img底部空白
<img>元素底部为何有空白? 问题: 最近听网课遇到这样一个问题,先po出代码如下: <!--html--> <div class="top"> ...
- SVN中trunk,branches,tags用法详解(转载)
转载出处:http://www.cnblogs.com/dafozhang/archive/2012/06/28/2567769.html Subversion是一个自由开源的版本控制系统.在Subv ...
- 爬虫学习(十六)——jsonpath
jsonpath介绍 jsonpath是一种信息抽取类库,是从json文档中抽取指定信息的工具,提供多种语言实现的版本 jsonpath对json来说,就相当于xpath对于xml jsonpath和 ...
- VMware虚拟机安装CentOS 7 Minimal 详细全过程
VMware虚拟机安装CentOS 7 Minimal 详细全过程记录,并进行CentOS7 的网络配置,本次安装的CentOS镜像版本为官方网站下载的 CentOS-7-x86_64-Minimal ...
- linux面试集
shell:1.$# 和 $*之类的特殊变量 特殊变量列表 变量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n是一个数字,表示第几个参数.例如,第一个参数就是$1 $# 传递给脚本或 ...
- JQuery制作网页—— 第四章JavaScript对象及初识面向对象
1.对象:在JavaScript中,所有事物都是对象,如字符串.数值.数组.函数等. JavaScript中的基本数据类型: number(数值类型) string(字符串类型) boolean ...
- linux学习(2)——文件和目录管理
(二) 一:绝对路径和相对路径 ...
- MyFirstDay(附6篇python亲历面试题)
一直以来都是在看别人写的内容,学习前辈们的经验,总感觉自己好像没有什么值得拿出来分享和交流的知识,最近在准备换工作(python后端开发),坐标上海,2019年3月,半个月面了6家(感觉效率是真不高. ...
- 搭建Linpack
环境:vmware workstation14 + centos7(linux基本都可以) 一.开始安装mpich 1. 解决依赖gcc gcc-gfortran sudo yum install g ...
- Still unable to dial persistent://blog.csdn.net:80 after 3 attempts
动不动电脑有些网站打不开了,还报错: Still unable to dial persistent://blog.csdn.net:80 after 3 attempts 为什么呢? 是dns坏了? ...