维护信息的方式十分巧妙~

维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点.

这样非常方便维护,进行区间合并,进行子树维护

很多时候在维护东西的时候最大/最小/深度最小/深度最大会相对容易维护,所以如果用树剖/LCT维护信息时发现很难维护的话可以采用这种套路.

因为动态树是可以维护子树信息的,也可以 ​,所以如果维护深度最深的信息的话只需 ​ 就可以做到.

code:

#include <bits/stdc++.h>
#define N 100006
#define inf 1000000
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,edges;
int hd[N],to[N<<1],nex[N<<1],col[N];
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
struct Link_Cut_Tree
{
#define lson p[x].ch[0]
#define rson p[x].ch[1]
struct Node
{
int ch[2],f,size,lmn,rmn;
multiset<int>s;
int get() { return s.empty()?inf:*s.begin(); }
}p[N];
int get(int x) { return p[p[x].f].ch[1]==x; }
int isrt(int x) { return !(p[p[x].f].ch[0]==x||p[p[x].f].ch[1]==x); }
void pushup(int x)
{
p[x].size=p[lson].size+p[rson].size+1;
p[x].lmn=min(p[lson].lmn, p[lson].size+min(col[x]?0:inf, min(p[x].get(), p[rson].lmn+1)));
p[x].rmn=min(p[rson].rmn, p[rson].size+min(col[x]?0:inf, min(p[x].get(), p[lson].rmn+1)));
}
void rotate(int x)
{
int old=p[x].f,fold=p[old].f,which=get(x);
if(!isrt(old)) p[fold].ch[p[fold].ch[1]==old]=x;
p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old;
p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold;
pushup(old),pushup(x);
}
void splay(int x)
{
int u=x,v=0,fa;
for(;!isrt(u);u=p[u].f);
for(u=p[u].f;(fa=p[x].f)!=u;rotate(x))
if(p[fa].f!=u)
rotate(get(fa)==get(x)?fa:x);
}
void Access(int x)
{
for(int y=0;x;y=x,x=p[x].f)
{
splay(x);
if(rson)
{
p[x].s.insert(p[rson].lmn+1);
}
if(y)
{
p[x].s.erase(p[x].s.find(p[y].lmn+1));
}
rson=y;
pushup(x);
}
}
#undef lson
#undef rson
}lct;
void dfs(int u,int ff)
{
lct.p[u].f=ff;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==ff) continue;
dfs(v,u);
lct.p[u].s.insert(inf+1);
}
lct.pushup(u);
}
int main()
{
// setIO("input");
int i,j;
scanf("%d",&n);
for(i=1;i<n;++i)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
lct.p[0].lmn=lct.p[0].rmn=inf;
dfs(1,0);
int m;
scanf("%d",&m);
for(i=1;i<=m;++i)
{
int op,u;
scanf("%d%d",&op,&u);
if(op==0)
{
lct.Access(u);
lct.splay(u);
col[u]^=1;
lct.pushup(u);
}
else
{
lct.Access(u);
lct.splay(u);
printf("%d\n",lct.p[u].rmn>n?-1:lct.p[u].rmn);
}
}
return 0;
}

  

SPOJ 2939 QTREE5 LCT的更多相关文章

  1. SPOJ QTREE5 lct

    题目链接 对于每一个节点,记录这个节点所在链的信息: ls:(链的上端点)距离链内部近期的白点距离 rs:(链的下端点)距离链内部近期的白点距离 注意以上都是实边 虚边的信息用一个set维护. set ...

  2. QTREE5 - Query on a tree V——LCT

    QTREE5 - Query on a tree V 动态点分治和动态边分治用Qtree4的做法即可. LCT: 换根后,求子树最浅的白点深度. 但是也可以不换根.类似平常换根的往上g,往下f的拼凑 ...

  3. spoj 375 query on a tree LCT

    这道题是树链剖分的裸题,正在学LCT,用LCT写了,发现LCT代码比树链剖分还短点(但我的LCT跑极限数据用的时间大概是kuangbin大神的树链剖分的1.6倍,所以在spoj上是850ms卡过的). ...

  4. SPOJ OTOCI 动态树 LCT

    SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...

  5. SPOJ - OTOCI LCT

    OTOCI Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/problem/viewProblem. ...

  6. SPOJ QTREE4 lct

    题目链接 这个题已经处于花式tle了,改版后的spoj更慢了.. tle的话就多交几把... #include <iostream> #include <fstream> #i ...

  7. SPOJ QTREE3 lct

    题目链接 题意: 给定n个点 q个询问 以下n-1行给出树边,点有黑或白色.初始化为白色 以下q行: 询问有2种: 1. 0 x 把x点黑变白,白变黑 2.1 x 询问Path(1,x)路径上第一个黑 ...

  8. SPOJ QTREE2 lct

    题目链接 题意: 给一棵树.有边权 1.询问路径的边权和 2.询问沿着路径的第k个点标. 思路:lct裸题. #include <iostream> #include <fstrea ...

  9. SPOJ2939 QTREE5(LCT维护子树信息)

    QWQ嘤嘤嘤 此题正规题解应该是边分治??或者是树剖(总之不是LCT) 但是我这里还是把它当成一个LCT题目来做 首先,这个题的重点还是在update上 因为有\(makeroot\)这个操作的存在, ...

随机推荐

  1. PAT(B) 1081 检查密码(Java)

    题目链接:1081 检查密码 (15 point(s)) 题目描述 本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能.该网站要求用户设置的密码必须由不少于6个字符组成,并且只能有英文字母 ...

  2. WUSTOJ 1318: 区间的连通性(Java)

    题目链接:

  3. 正整数序列 Help the needed for Dexter ,UVa 11384

    题目描述 Description 给定正整数n,你的任务是用最少的操作次数把序列1, 2, …, n中的所有数都变成0.每次操作可从序列中选择一个或多个整数,同时减去一个相同的正整数.比如,1,2,3 ...

  4. Centos 安装PHP-redis扩展

    从https://pecl.php.net/package/redis   里面找到自己安装的Redis对应版本的redis 1.获取已经安装的Redis版本扩展我这边安装的是4.0.1版本 wget ...

  5. Spring BeanFactory 与 FactoryBean 的区别

    BeanFactory 和 FactoryBean 都是Spring Beans模块下的接口 BeanFactory是spring简单工厂模式的接口类,spring IOC特性核心类,提供从工厂类中获 ...

  6. 转 无损转换Image为Icon

    不可取 var handle = bmp.GetHicon();    //得到图标句柄return Icon.FromHandle(handle); //通过句柄得到图标 可取 /// <su ...

  7. 线程一(lock)

    对于线程同步操作最简单的一种方式就是使用 lock 关键字,通过 lock 关键字能保证加锁的线程只有在执行完成后才能执行其他线程.   lock 的语法形式如下. lock(object) {    ...

  8. Django Rest framework序列化流程

    目录 一 什么是序列化 二 Django REST framework配置流程之Serializer 三 Django REST framework配置流程之ModelSerializer 一 什么是 ...

  9. 前端之:传统的DOM是如何渲染的?

    a.纯后端渲染:页面发送请求,后端服务器中将数据拼成完整DOM树,并转换成一个字节流作为HTTP Response的body返回给浏览器.优点在于 返回的HTTP Response是包含着全部页面内容 ...

  10. html5细线表格制作

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...