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. 解决更新页面版本后用户需CTRL+F5强刷才能应用最新页面

    设置文件永远不从缓存读取 第一步:在html文件设置文件不缓存 <!DOCTYPE html> <html lang="en" class="theme ...

  2. (四)、Docker 镜像

    1.Docker镜像是什么? 镜像是一种轻量级.可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码.运行时.库.环境变量和配置文件. 2.Do ...

  3. 开关电源(DC-DC)与LDO电源的区别---纹波

    https://blog.csdn.net/edadoc2013/article/details/78435775

  4. 基于Vue的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式

    在基于Vue的工作流项目模块中,我们在查看表单明细的时候,需要包含公用表单信息,特定表单信息两部分内容.前者表单数据可以统一呈现,而后者则是不同业务的表单数据不同.为了实现更好的维护性,把它们分开作为 ...

  5. 计算机网络之传输层(传输层提供的服务及功能概述、端口、套接字--Socket、无连接UDP和面向连接TCP服务)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105451022 学习课程:<2019王道考研计算机网络> 学习目的 ...

  6. 洛谷 P3209 [HNOI2010] 平面图判定

    链接: P3209 题意: 给出 \(T\) 张无向图 \((T\leq100)\),并给出它对应的哈密顿回路,判断每张图是否是平面图. 分析: 平面图判定问题貌似是有线性做法的,这里给出链接,不是本 ...

  7. linux中解压.tgz, .tar.gz ,zip ,gz, .tar文件

    转载:https://blog.csdn.net/fu6543210/article/details/7984578 将.tgz文件解压在当前目录: tar zxvf MY_NAME.tgz 将.ta ...

  8. 碰撞的蚂蚁 牛客网 程序员面试金典 C++ Java Python

    碰撞的蚂蚁 牛客网 程序员面试金典 C++ Java Python 题目描述 在n个顶点的多边形上有n只蚂蚁,这些蚂蚁同时开始沿着多边形的边爬行,请求出这些蚂蚁相撞的概率.(这里的相撞是指存在任意两只 ...

  9. 数组模拟双链表,你get到了吗?

    数组模拟双链表 通过前面的学习我们知道单链表是单个指针指向操作,那么通过类比我们可以把指针设定为两个,并且让它们分别指向前后数据,这就是"双向链表".使用这种链表,不仅可以从前往后 ...

  10. oeasy教您玩转vim - 56 - # 字符可视化模式

    ​ 可视化编辑 回忆上节课内容 我们学习了关于模式匹配中使用参数 单个参数 :%s/<h2>\(.*\)</h2>/ - \1/g 多个参数 :%s/<img src=\ ...