我们发现,这个染色的操作他就很像LCT中access的操作(为什么??),然后就自然而然地想到,其实一个某条路径上的颜色数量,就是我们做一个只有access操作的LCT,这条路径经过的splay的数量

然后考虑怎么样来维护这个数量。access的过程中,有实边变虚边、虚边变实边的操作,对应过来,实边变虚边,就是以(断掉的那个子splay树中的在原树中最浅的点)为根的子树中 每个点到根的颜色数++(多拆出来了一个splay嘛),虚边变实边同理,不过是--

这样就可以再用一个线段树维护dfs序了,第三个询问就是线段树上的最大值

第二个询问,如果有x,y,lca,那x到y路径上的颜色数就是num[x]+num[y]-2*num[lca]+1,num[i]就是刚才线段树记的那个

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=1e5+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,M;
int eg[maxn*][],egh[maxn],ect;
int dep[maxn],dfn[maxn][],fa[maxn],ch[maxn][],tot;
int bf[maxn][],ma[maxn*],laz[maxn*],id[maxn]; inline void adeg(int a,int b){
eg[++ect][]=b,eg[ect][]=egh[a];egh[a]=ect;
} void dfs(int x){
dfn[x][]=++tot;id[tot]=x;
for(int i=;bf[x][i]&&bf[bf[x][i]][i];i++)
bf[x][i+]=bf[bf[x][i]][i];
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];
if(b==fa[x]) continue;
fa[b]=bf[b][]=x;dep[b]=dep[x]+;
dfs(b);
}
dfn[x][]=tot;
} inline int getlca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=log2(dep[x]-dep[y]);i>=&&dep[x]!=dep[y];i--){
if(dep[bf[x][i]]>=dep[y])
x=bf[x][i];
}
if(x==y) return x;
for(int i=log2(dep[x]);i>=;i--){
if(bf[x][i]!=bf[y][i])
x=bf[x][i],y=bf[y][i];
}
return bf[x][];
} inline bool nroot(int x){return x==ch[fa[x]][]||x==ch[fa[x]][];}
inline bool isrt(int x){return x==ch[fa[x]][];} inline void rotate(int x){
int f=fa[x],ff=fa[fa[x]];bool b=isrt(x);
fa[x]=ff;if(nroot(f)) ch[ff][isrt(f)]=x;
fa[ch[x][!b]]=f,ch[f][b]=ch[x][!b];
fa[f]=x,ch[x][!b]=f;
} inline void splay(int x){
while(nroot(x)&&nroot(fa[x])){
if(isrt(x)==isrt(fa[x])) rotate(fa[x]);
else rotate(x);rotate(x);
}if(nroot(x)) rotate(x);
} inline int getl(int x){
while(ch[x][]) x=ch[x][];
return x;
} inline void update(int p){ma[p]=max(ma[p<<],ma[p<<|]);}
inline void pushdown(int p){
if(!laz[p]) return;
int a=p<<,b=p<<|;
laz[a]+=laz[p],laz[b]+=laz[p];
ma[a]+=laz[p],ma[b]+=laz[p];
laz[p]=;
} inline void build(int p,int l,int r){
if(l==r) ma[p]=dep[id[l]];
else{
int m=l+r>>;
build(p<<,l,m);
build(p<<|,m+,r);
update(p);
}
}
inline void add(int p,int l,int r,int x,int y,int z){
// printf("%d %d %d %d %d\n",p,l,r,x,y);
if(x<=l&&r<=y){
ma[p]+=z;laz[p]+=z;
}else{
pushdown(p);
int m=l+r>>;
if(x<=m) add(p<<,l,m,x,y,z);
if(y>=m+) add(p<<|,m+,r,x,y,z);
update(p);
}
}
inline int query(int p,int l,int r,int x,int y){
if(!x||!y) return ;
if(x<=l&&r<=y) return ma[p];
pushdown(p);
int m=l+r>>,re=;
if(x<=m) re=query(p<<,l,m,x,y);
if(y>=m+) re=max(re,query(p<<|,m+,r,x,y));
return re;
} inline void access(int x){
for(int y=;x;y=x,x=fa[x]){
splay(x);
int a=getl(ch[x][]),b=getl(y);
// printf("!%d %d\n",a,b);
if(a) add(,,N,dfn[a][],dfn[a][],);
if(b) add(,,N,dfn[b][],dfn[b][],-);
ch[x][]=y;
}
} inline int gettop(int x){
while(nroot(x)) x=fa[x];
return x;
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd(),M=rd();
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}
dep[]=;dfs();
build(,,N);
for(i=;i<=M;i++){
int a=rd(),x=rd();
if(a==) access(x);
else if(a==){
int y=rd();
int lca=getlca(x,y);
// printf("%d %d\n",x,y)
printf("%d\n",query(,,N,dfn[x][],dfn[x][])+
query(,,N,dfn[y][],dfn[y][])-
*query(,,N,dfn[lca][],dfn[lca][])+);
}else{
printf("%d\n",query(,,N,dfn[x][],dfn[x][]));
}
}
return ;
}

bzoj4817/luogu3703 树点涂色 (LCT+dfs序+线段树)的更多相关文章

  1. [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 692  Solved: 408[Submit][Status ...

  2. BZOJ.4817.[SDOI2017]树点涂色(LCT DFS序 线段树)

    题目链接 操作\(1.2\)裸树剖,但是操作\(3\)每个点的答案\(val\)很不好维护.. 如果我们把同种颜色的点划分到同一连通块中,那么向根染色的过程就是Access()! 最初所有点间都是虚边 ...

  3. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  4. [BZOJ3779]重组病毒(LCT+DFS序线段树)

    同[BZOJ4817]树点涂色,只是多了换根操作,分类讨论下即可. #include<cstdio> #include<algorithm> #define lc ch[x][ ...

  5. [BZOJ4817][SDOI2017]树点涂色:Link-Cut Tree+线段树

    分析 与[BZOJ3779]重组病毒唯一的区别是多了一个链上求实链段数的操作. 因为每条实链的颜色必然不相同且一条实链上不会有两个深度相同的点(好像算法的正确性和第二个条件没什么关系,算了算了),画图 ...

  6. BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)

    题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...

  7. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

  8. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

  9. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

随机推荐

  1. 【强化学习】python 实现 q-learning 例三(例一改写)

    本文作者:hhh5460 本文地址:https://www.cnblogs.com/hhh5460/p/10139738.html 例一的代码是函数式编写的,这里用面向对象的方式重新撸了一遍.好处是, ...

  2. 爬虫学习--http请求详解

    上篇博客里面写了,爬虫就是发http请求(浏览器里面打开发送的都是http请求),然后获取到response,咱们再从response里面找到想要的数据,存储到本地. 咱们本章就来说一下什么是http ...

  3. C# 获取文件MD5值的方法

    可用于对比文件是否相同 /// <summary> /// 获取文件MD5值 /// </summary> /// <param name="fileName& ...

  4. 5 questions

    1.软件开发中有哪几种过程模型? 2.详细设计有哪几种描述方法? 3.什么是需求分析? 4.软件设计的基本原理包括哪些内容? 5.简述文档在软件工程中的作用? 逸翔.

  5. 《Linux内核设计与实现》第四章学习笔记

    <Linux内核设计与实现>第四章学习笔记           ——进程调度 姓名:王玮怡  学号:20135116 一.多任务 1.多任务操作系统的含义 多任务操作系统就是能同时并发地交 ...

  6. 《linux内核设计与分析》内核模块编程

    内核模块编程 一.准备工作 虚拟机:VMware Workstation 12操作系统:ubuntu当前内核版本:linux-headers-4.4.0-22-generic 二.有关于内核模块的知识 ...

  7. shiro课程的学习

    1.shiro的课程目标 (1)shiro的整体框架 各组件的概念 (2)shiro 认证 授权的过程 (3)shiro自定义的Reaml Filter (4)shiro session 管理 (5) ...

  8. JAVA面对对象(三)——Super、static、final关键字

    Super 使用super关键字可以直接调用父类中的构造方法.属性.普通方法 super调用父类构造方法的操作,与this调用构造方法一样,语句必须放在子类构造方法的首行 public class P ...

  9. 【转】GPS定位准确度CEP、RMS

    转自:http://blog.sina.com.cn/s/blog_70f96fda0101lcb9.html CEP和RMS是GPS的定位准确度(俗称精度)单位,是误差概率单位.就拿2.5M CEP ...

  10. Java abstract interface与 interface的区别

    我们常常遇到abstract class与 interface的区别,今天却遇到了abstract interface,感觉interface不用abstract再修饰了啊.结论:事实也确实如此,编译 ...