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,甚至出现负数,调啊调啊调啊调~~~ 只会旋转最大值和最小值,以最小 ...
随机推荐
- mysql_old_wrong
DELIMITER $ create trigger auto_post_person_pointafter insert on post for each rowbeginupdate person ...
- 722. Remove Comments
class Solution { public: vector<string> removeComments(vector<string>& source) { vec ...
- 汉罗塔问题——Python
汉罗塔问题就是一个循环的过程:* (有两种情况) 如果被移动盘只有一个盘子,可以直接移动到目的盘 但是被移动盘有多个盘子,就先需要将上面的n-1个盘子通过目的盘移动到辅助盘,然后将被移动盘最下面一个盘 ...
- PHP.18-图片等比例缩放
图片等比例缩放 自定义函数ImageUpdateSize($pricname, $maxx, $maxy, $pre) 1.$pricname:被缩放的图片源(路径):2.$maxx,$maxy:缩放 ...
- ClassNotFountException 与 NoClassDefineError
一 知识准备 NoClassDefFoundError:正如它们的名字所说明的是一个错误 (Error),而ClassNotFoundException是一个异常.正如上一章节所说Exception和 ...
- SpringMVC + MyBatis简单示例
该项目基于Maven开发,该项目中包含了MyBatis自动创建表的功能,具体实现查阅MyBatis---自动创建表 源码下载 配置 maven支持pom.xml <project xmlns=& ...
- 8 定制10MINs 3
1. <div class="ui inverted red basic segment"> <h3 class="ui header"> ...
- Android onConfigurationChanged 收不到回调
我返现,90度横屏 旋转到270度横屏onConfigurationChanged 是收不到回掉的.尽管清单里面声明了什么: android:configChanges="orientati ...
- Linux下单机安装部署kafka及代码实现
技术交流群:233513714 这几天研究了kafka的安装及使用,在网上找了很多教程但是均以失败告终,直到最后想起网络方面的问题最终才安装部署成功,下面就介绍一下kafka的安装部署及代码实现 一. ...
- 关于update 表名 set 字段1 = 值1 and 字段2 = 值2的执行结果说明
技术交流群: 233513714 如果执行了以下的语句,则brand等于‘OPPO’条件所对应的数据不会做改变,但是sequence_brand列除brand = 'OPPO'之外的所有数据都会变为0 ...