lmn u 表示 u 所在splay子树最上方点距离最近的白点

rmn u 表示 u 所在splay子树最下方点距离最近的白点

开一个set维护所有虚儿子能走到的最近的白点的距离

考虑pushup,

对于它的右儿子,考虑要么从这个点走向它的虚儿子,要么通过它左子树中深度最大的点走。

对于它的左儿子要么从这个点走向它的虚儿子,要么通过它右子树的最浅点走。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
#define MAXN 100006
int n , m;
int ch[MAXN][2] , siz[MAXN] , fa[MAXN] , lmn[MAXN] , rmn[MAXN];
int w[MAXN];
multiset<int> S[MAXN]; bool notr( int u ) {
return ( ch[fa[u]][0] == u ) || ( ch[fa[u]][1] == u );
}
void pushup( int u ) {
int ls = ch[u][0] , rs = ch[u][1];
siz[u] = siz[ls] + siz[rs] + 1;
if( w[u] ) {
lmn[u] = min( lmn[ls] , siz[ls] );
rmn[u] = min( rmn[rs] , siz[rs] );
return;
}
int t = S[u].empty() ? 0x3f3f3f3f : *S[u].begin();
lmn[u] = min( lmn[ls] , lmn[rs] + siz[ls] + 1 );
rmn[u] = min( rmn[rs] , rmn[ls] + siz[rs] + 1 );
lmn[u] = min( lmn[u] , t + siz[ls] ) , rmn[u] = min( rmn[u] , t + siz[rs] );
}
void rotate( int x ) {
int f = fa[x] , g = fa[f] , w = ch[fa[x]][1] == x;
int wf = ch[g][1]==f , k = ch[x][w^1];
if( notr(f) ) ch[g][wf] = x; ch[f][w] = k , ch[x][w^1] = f;
fa[f] = x , fa[k] = f , fa[x] = g;
pushup( f ) , pushup( x );
}
void splay( int x ) {
int f , g;
while( notr( x ) ) {
f = fa[x] , g = fa[f];
if( notr( f ) )
rotate( (ch[f][0]==x)^(ch[g][0]==f) ? x : f );
rotate( x );
}
}
void access( int x ) {
for( int p = 0 ; x ; ( p = x , x = fa[x] ) ) {
splay( x );
if( ch[x][1] ) S[x].insert( 1 + lmn[ch[x][1]] );
if( p ) S[x].erase( S[x].find( 1 + lmn[p] ) );
ch[x][1] = p , pushup( x );
}
} int head[MAXN] , nex[MAXN << 1] , to[MAXN << 1] , ecn;
void ade( int u , int v ) {
nex[++ ecn] = head[u] , to[ecn] = v , head[u] = ecn;
}
void dfs( int u , int f ) {
fa[u] = f;
for( int i = head[u] ; i ; i = nex[i] ) {
int v = to[i];
if( v == f ) continue;
dfs( v , u );
S[u].insert( 1 + 0x3f3f3f3f );
} } int main() {
cin >> n;
for( int i = 1 , u , v ; i < n ; ++ i ) {
scanf("%d%d",&u,&v);
ade( u , v ) , ade( v , u );
}
dfs( 1 , 0 );
lmn[0] = rmn[0] = 0x3f3f3f3f;
for( int i = 1 ; i <= n ; ++ i )
lmn[i] = rmn[i] = 0x3f3f3f3f , siz[i] = 1;
cin >> m;
int opt , u;
while( m-- ) {
scanf("%d%d",&opt,&u);
// cout << S[1].size() << endl;
if( opt == 0 ) {
access( u ) , splay( u );
w[u] ^= 1;
pushup( u );
} else {
access( u ) , splay( u );
printf("%d\n",rmn[u] > n ? -1 : rmn[u]);
}
}
}

Qtree V的更多相关文章

  1. 模版 动态 dp

    模版 动态 dp 终于来写这个东西了.. LG 模版:给定 n 个点的数,点有点权, $ m $ 次修改点权,求修改完后这个树的最大独立集大小. 我们先来考虑朴素的最大独立集的 dp \[dp[u][ ...

  2. SPOJ QTREE Query on a tree V

    You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are number ...

  3. SPOJ QTREE Query on a tree V ——动态点分治

    [题目分析] QTREE4的弱化版本 建立出分治树,每个节点的堆表示到改点的最近白点距离. 然后分治树上一直向上,取min即可. 正确性显然,不用担心出现在同一子树的情况(不会是最优解),请自行脑补. ...

  4. 激!QTREE系列

    我现在才开始刷 QTREE 是不是太弱了?算了不管他…… QTREE: 树链剖分裸题(据说 lct 会超时……该说是真不愧有 spoj 的气息吗?) #include <cstdio> # ...

  5. Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划

    题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆   输入文件:qtree.in  ...

  6. SPOJ QTREE 系列解题报告

    题目一 : SPOJ 375 Query On a Tree http://www.spoj.com/problems/QTREE/ 给一个树,求a,b路径上最大边权,或者修改a,b边权为t. #in ...

  7. QTREE - Query on a tree

    QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog ...

  8. 树链剖分-SPOJ375(QTREE)

    QTREE - Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, a ...

  9. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

随机推荐

  1. Golang通脉之面向对象

    面向对象的三大特征: 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不同实现方式 Go并不是一个纯 ...

  2. SpringCloud-初见

    目录 前言 微服务概述 微服务与微服务架构 微服务优缺点 微服务技术栈 为什么选择SpringCloud作为微服务架构 SpringCloud入门 SpringCloud和SpringBoot的关系 ...

  3. [Git系列] Git 基本概念

    版本控制系统 版本控制系统是一种帮助软件开发者实现团队合作和历史版本维护的软件,一个版本控制系统应具备以下列出的这几个基本功能: 允许开发者并发工作: 不允许一个开发者覆写另一个开发者的修改: 保存所 ...

  4. 离线状态迁移Anaconda虚拟环境

    离线状态迁移Anaconda虚拟环境 同样是项目需求,需要布署的服务器上的Anaconda安装到了普通账户下 而后续所有的内容都需要通过root账户进行操作,而服务器已经布署,联网比较麻烦 本文提出, ...

  5. Windows平台编译器相关的几个预定义宏

    WIN32 是在windows.h 中定义的宏,包含winodws.h则定义该宏 _WIN32/_WIN64跟windows平台有关的宏,_WIN32在windows   32位和64位下都有该宏,_ ...

  6. Shadertoy 教程 Part 2 - 圆和动画

    Note: This series blog was translated from Nathan Vaughn's Shaders Language Tutorial and has been au ...

  7. hdu 5018 Revenge of GCD

    题意: 给你两个数:X和Y  .输出它们的第K大公约数.若不存在输出 -1 数据范围: 1 <= X, Y, K <= 1 000 000 000 000 思路: 它俩的公约数一定是gcd ...

  8. WPF进阶技巧和实战03-控件(3-文本控件及列表控件)

    系列文章链接 WPF进阶技巧和实战01-小技巧 WPF进阶技巧和实战02-布局 WPF进阶技巧和实战03-控件(1-控件及内容控件) WPF进阶技巧和实战03-控件(2-特殊容器) WPF进阶技巧和实 ...

  9. Linux 文本三剑客之 sed

    Linux 系统中一切皆文件. 文件是个文本.可以读.可以写,如果是二进制文件,还能执行. 在使用Linux的时候,大都是要和各式各样文件打交道.熟悉文本的读取.编辑.筛选就是linux系统管理员的必 ...

  10. 【微服务理论】API + BFF

    对于微服务,常见的架构模型就是API网关+服务. API网关实现鉴权.负载均衡.中间件等公共入口逻辑. 服务实现具体的业务功能. 那么,API网关设计中又有什么坑呢? 1.0版本 直接将服务穿透到外网 ...