[CF414E]Mashmokh's Designed Problem
题意:给一棵树,有三个操作:①询问两点$(x,y)$之间的距离②把$x$和原来的父亲断开并连到它的$h$级祖先,作为新父亲最右的儿子③询问与根节点距离为$k$的点中最右的点是哪个点
用出栈入栈序$s_{1\cdots 2n}$来维护整棵树,入栈记$1$出栈记$-1$,那么一个节点$x$的深度就是$\sum\limits_{i=1}^{in_x}s_x$
每个平衡树节点记1.这个节点是出栈还是入栈2.子树和3.最大前缀和4.最小前缀和,那么我们就可以在平衡树上二分找到最右的深度为$d$的节点(注意如果找到的是出栈点应该返回父亲,因为有个$-1$)
对于操作①,把$(in_x,in_y)$提出来,那么这个区间内深度最小的节点就是$lca_{x,y}$
对于操作②,找到那个$h$级祖先,直接序列移动即可
对于操作③,直接找
为了使我的splay不残废就用splay写了一下
注意因为邻接表的性质,加边要倒着加
#include<stdio.h>
int ch[200010][2],fa[200010],v[200010],s[200010],mx[200010],mn[200010],h[100010],nex[100010],to[100010],pa[100010],tmp[100010],p[200010],M,rt;
void add(int a,int b){
M++;
to[M]=b;
nex[M]=h[a];
h[a]=M;
}
void dfs(int x){
M++;
p[M]=(x<<1)-1;
v[(x<<1)-1]=1;
for(int i=h[x];i;i=nex[i]){
pa[to[i]]=x;
dfs(to[i]);
}
M++;
p[M]=x<<1;
v[x<<1]=-1;
}
#define ls ch[x][0]
#define rs ch[x][1]
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
void pushup(int x){
s[x]=s[ls]+s[rs]+v[x];
mx[x]=max(mx[ls],s[ls]+v[x]+max(mx[rs],0));
mn[x]=min(mn[ls],s[ls]+v[x]+min(mn[rs],0));
}
int build(int l,int r){
int mid=(l+r)>>1;
int&x=p[mid];
if(l<mid){
ls=build(l,mid-1);
fa[ls]=x;
}
if(mid<r){
rs=build(mid+1,r);
fa[rs]=x;
}
pushup(x);
return x;
}
void rot(int x){
int y,z,f,B;
y=fa[x];
z=fa[y];
f=(ch[y][0]==x);
B=ch[x][f];
fa[x]=z;
fa[y]=x;
if(B)fa[B]=y;
ch[x][f]=y;
ch[y][f^1]=B;
if(ch[z][0]==y)ch[z][0]=x;
if(ch[z][1]==y)ch[z][1]=x;
pushup(y);
pushup(x);
}
void splay(int x,int gl){
int y,z;
while(fa[x]!=gl){
y=fa[x];
z=fa[y];
if(z!=gl)rot((ch[z][0]==y&&ch[y][0]==x)||(ch[z][1]==y&&ch[y][1]==x)?y:x);
rot(x);
}
}
int getdis(int x,int y){
x=(x<<1)-1;
y=(y<<1)-1;
int dx,dy,dl;
splay(x,0);
dx=s[ls]+v[x];
splay(y,0);
dy=s[ch[y][0]]+v[y];
splay(x,0);
splay(y,x);
rt=x;
dl=min(dx,dy);
if(ls==y)
dl=min(dl,s[ch[y][0]]+v[y]+mn[ch[y][1]]);
else
dl=min(dl,s[ls]+v[x]+mn[ch[y][0]]);
return dx+dy-(dl<<1);
}
int find(int x,int d){
if(mx[rs]>=d-s[ls]-v[x]&&mn[rs]<=d-s[ls]-v[x])return find(rs,d-s[ls]-v[x]);
if(s[ls]+v[x]==d)return(x&1)?(x+1)>>1:pa[x>>1];
return find(ls,d);
}
int pre(int x){
splay(x,0);
for(x=ls;rs;x=rs);
return x;
}
int nx(int x){
splay(x,0);
for(x=rs;ls;x=ls);
return x;
}
void change(int u,int h){
int x=(u<<1)-1,L,R,t;
splay(x,0);
pa[u]=find(ls,s[ls]+v[x]-h);
L=pre(x);
R=nx(u<<1);
splay(L,0);
splay(R,L);
t=ch[R][0];
ch[R][0]=0;
pushup(R);
pushup(L);
L=pre(pa[u]<<1);
R=(pa[u]<<1);
splay(L,0);
splay(R,L);
ch[R][0]=t;
fa[t]=R;
pushup(R);
pushup(L);
rt=L;
}
#define inf 1000000000
int main(){
mx[0]=-inf;
mn[0]=inf;
int n,m,i,x,y;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&y);
for(x=1;x<=y;x++)scanf("%d",tmp+x);
for(x=y;x>0;x--)add(i,tmp[x]);
}
M=0;
dfs(1);
rt=build(1,n<<1);
while(m--){
scanf("%d%d",&i,&x);
if(i!=3)scanf("%d",&y);
if(i==1)printf("%d\n",getdis(x,y));
if(i==2)change(x,y);
if(i==3)printf("%d\n",find(rt,x+1));
}
}
[CF414E]Mashmokh's Designed Problem的更多相关文章
- @codeforces - 414E@ Mashmokh's Designed Problem
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一棵 n 个点的树,每个点的儿子是有序的. 现给定 m 次操 ...
- [JZOJ3691] 【CF414E】Mashmokh's Designed tree
题目 题目大意 给你一棵树,接下来对这棵树进行三种操作: 1.询问两点之间的距离. 2.让某个点变为它原来的第\(h\)个祖先的最后一个儿子. 3.求\(dfs\)序中最后一个深度为\(k\)的点. ...
- HDU1086You can Solve a Geometry Problem too(判断线段相交)
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- [转]Amazon DynamoDB – a Fast and Scalable NoSQL Database Service Designed for Internet Scale Applications
This article is from blog of Amazon CTO Werner Vogels. -------------------- Today is a very exciting ...
- hdu 1086 You can Solve a Geometry Problem too
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- you can Solve a Geometry Problem too(hdoj1086)
Problem Description Many geometry(几何)problems were designed in the ACM/ICPC. And now, I also prepare ...
- C#学习日志 day10 -------------- problem statement
Revision History Date Issue Description Author 15/May/2015 1.0 Finish most of the designed function. ...
- HDU 4716 A Computer Graphics Problem
A Computer Graphics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- (hdu step 7.1.2)You can Solve a Geometry Problem too(乞讨n条线段,相交两者之间的段数)
称号: You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/ ...
随机推荐
- json 串转成 java 对象再拼接成前台 html 元素
获取商品参数 json 串,转成 java 对象,再拼接成前台 html 的Service方法 @Override public String getItemParam(Long itemId) { ...
- Endnote 中文参考文献样式修改版
http://blog.yuelong.info/post/endnote-gbt7714-2005.html 很多人不知道 EndNote 是自带中文参考文献引用样式的,即符合<文后参考文献著 ...
- HTML5 视频直播
目前视频直播,尤其是移动端的视频直播已经火到不行了,基本上各大互联网公司都有了自己的直播产品,所以对于直播的一些基本知识和主要技术点也要有所了解,本次分享就向大家介绍一下其中的奥秘. 内容大体框架: ...
- apply()和call()
每个函数都包含俩个非继承而来的方法:apply() 和 call(),这俩个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值,以扩充函数赖以运行的作用域.一般来讲,thi ...
- 【hdu1251-统计难题】Trie
http://acm.hust.edu.cn/vjudge/problem/16379 题意:给定多个单词,多次询问符合某前缀的单词有多少个. 题解:tire.数组开了5*10^6才A,不然就RE. ...
- CodeVS1747_NOI2002_荒岛野人_Savage_C++
题目:http://codevs.cn/problem/1747/ 对于一个环,我们经常用取余来表示它走过若干圈后的位置 那么第 i 个野人第 x 年时所在的位置可表示为:(c[i]+p[i]*x)% ...
- bzoj 2039 最小割模型
比较明显的网络流最小割模型,对于这种模型我们需要先求获利的和,然后减去代价即可. 我们对于第i个人来说, 如果选他,会耗费A[I]的代价,那么(source,i,a[i])代表选他之后的代价,如果不选 ...
- 用 C# 代码如何实现让你的电脑关机,重启,注销,锁定,休眠,睡眠
简介 本文讲述了用 C# 代码如何实现让你的电脑关机,重启,注销,锁定,休眠,睡眠. 如何实现 首先,使用 using 语句添加我们需要的命名空间: using System.Diagnostics; ...
- C++高精度
整理了一下高精度,虽然可用java,但很多时候还是C++写的方便. 附上kuangbin神的高精度模板(HDU1134 求卡特兰数) #include <iostream> #includ ...
- efi转bios详细说明
前言 制作好的efi格式的ubuntu15.10系统放到服务器主板上启动不了,于是将其改为bios格式,发现问题解决了,成功登入系统.下面是操作过程的一个记录. 测试环境 目标环境 系统: Ubunt ...