传送门

解题思路

  跟重组病毒这道题很像。只是有了一个询问\(2\)的操作,然后询问\(2\)的答案其实就是\(val[x]+val[y]-2*val[lca(x,y)]+1\)(画图理解)。剩下的操作跟那道题就一样了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm> using namespace std;
const int MAXN = 100005; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?x:-x;
} int n,m,head[MAXN],cnt,to[MAXN<<1],nxt[MAXN<<1];
int dep[MAXN],siz[MAXN],fa[MAXN],Fa[MAXN],L[MAXN];
int top[MAXN],id[MAXN],wt[MAXN],num,son[MAXN];
int Max[MAXN<<2],ll[MAXN],tag[MAXN<<2]; inline int max(int x,int y){
return x>y?x:y;
} inline void add(int bg,int ed){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
} void dfs1(int x,int f,int d){
fa[x]=f;siz[x]=1;dep[x]=d;ll[x]=x;Fa[x]=f;
int maxson=-1,u;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==f) continue;
dfs1(u,x,d+1);siz[x]+=siz[u];
if(siz[u]>maxson) {maxson=siz[u];son[x]=u;}
}
} void dfs2(int x,int topf){
top[x]=topf;id[x]=++num;wt[num]=dep[x];
if(!son[x]) return;dfs2(son[x],topf);int u;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==son[x] || u==fa[x]) continue;
dfs2(u,u);
}
} inline void pushdown(int x){
Max[x<<1]+=tag[x];Max[x<<1|1]+=tag[x];
tag[x<<1]+=tag[x];tag[x<<1|1]+=tag[x];
tag[x]=0;
} void build(int x,int l,int r){
if(l==r) {Max[x]=wt[l];return;}int mid=(l+r)>>1;
build(x<<1,l,mid);build(x<<1|1,mid+1,r);
Max[x]=max(Max[x<<1],Max[x<<1|1]);
} void update(int x,int l,int r,int L,int R,int k){
if(L<=l && r<=R) {
Max[x]+=k;tag[x]+=k;
return ;
}int mid=(l+r)>>1;if(tag[x]!=0) pushdown(x);
if(L<=mid) update(x<<1,l,mid,L,R,k);
if(mid<R) update(x<<1|1,mid+1,r,L,R,k);
Max[x]=max(Max[x<<1],Max[x<<1|1]);
} inline int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]) x=Fa[top[x]];
else y=Fa[top[y]];
}
return dep[x]<dep[y]?x:y;
} int query(int x,int l,int r,int L){
if(l==r) return Max[x];
int mid=(l+r)>>1;if(tag[x]!=0) pushdown(x);
if(L<=mid) return query(x<<1,l,mid,L);
else return query(x<<1|1,mid+1,r,L);
} inline int qRange(int x,int y){
return query(1,1,n,id[x])+query(1,1,n,id[y])-2*query(1,1,n,id[lca(x,y)])+1;
} int query_max(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return Max[x];
int mid=(l+r)>>1,ret=0;if(tag[x]!=0) pushdown(x);
if(L<=mid) ret=max(ret,query_max(x<<1,l,mid,L,R));
if(mid<R) ret=max(ret,query_max(x<<1|1,mid+1,r,L,R));
return ret;
} inline int qSon(int x){
return query_max(1,1,n,id[x],id[x]+siz[x]-1);
} namespace lct{
int ch[MAXN][2];
inline bool isroot(int x){
return (x!=ch[fa[x]][0] && x!=ch[fa[x]][1]);
}
inline bool check(int x){
return (x==ch[fa[x]][1]);
}
inline void pushup(int x){
if(ch[x][0]) ll[x]=ll[ch[x][0]];
else ll[x]=x;
}
inline void rotate(int x){
int y=fa[x],z=fa[y];bool chk=check(x);
if(!isroot(y)) ch[z][check(y)]=x;
ch[y][chk]=ch[x][chk^1];fa[ch[x][chk^1]]=y;
ch[x][chk^1]=y;fa[y]=x;fa[x]=z;pushup(y);pushup(x);
}
inline void splay(int x){
for(;!isroot(x);rotate(x))
if(!isroot(fa[x])) rotate(check(x)==check(fa[x])?fa[x]:x);
}
inline void access(int x){
for(int y=0;x;y=x,x=fa[x]){
splay(x);
if(y) update(1,1,n,id[ll[y]],id[ll[y]]+siz[ll[y]]-1,-1);
if(ch[x][1]) update(1,1,n,id[ll[ch[x][1]]],id[ll[ch[x][1]]]+siz[ll[ch[x][1]]]-1,1);
ch[x][1]=y;pushup(x);
}
}
} int main(){
n=rd(),m=rd();int x,y,opt;
for(int i=1;i<n;i++){
x=rd(),y=rd();
add(x,y);add(y,x);
}
dfs1(1,0,1);dfs2(1,1);build(1,1,n);
while(m--){
opt=rd();x=rd();
if(opt==1) lct::access(x);
if(opt==2) y=rd(),printf("%d\n",qRange(x,y));
if(opt==3) printf("%d\n",qSon(x));
}
return 0;
}

BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)的更多相关文章

  1. [Sdoi2017]树点涂色 [lct 线段树]

    [Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...

  2. 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树

    [BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...

  3. 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]

    树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...

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

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

  5. [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]

    题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...

  6. BZOJ4817[Sdoi2017]树点涂色——LCT+线段树

    题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ...

  7. bzoj4817 & loj2001 [Sdoi2017]树点涂色 LCT + 线段树

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4817 https://loj.ac/problem/2001 题解 可以发现这个题就是 bzo ...

  8. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  9. BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树

    同BZOJ3779. SDOI出原题,还是弱化版的. 吃枣药丸 #include <map> #include <cmath> #include <queue> # ...

随机推荐

  1. XML解析方式有哪些?

    1.DOM:要求解析器吧整个XML文档装载到内存,并解析成一个Document对象. (1).优点:元素与元素之间保留结构关系,故可以进行增删改查操作. (2).缺点:XML文档过大,可能出现内存溢出 ...

  2. h5判断设备是ios还是android

    var u = navigator.userAgent, app = navigator.appVersion;var isAndroid = u.indexOf('Android') > -1 ...

  3. Cross platform

    值得学习的C/C++语言开源项目 (1)ACE 庞大.复杂,适合大型项目.开源.免费,不依赖第三方库,支持跨平台. http://www.cs.wustl.edu/~schmidt/ACE.html ...

  4. 线性dp——1197D

    一开始没有什么头绪,后来注意到m<=10,考虑是否可以用dp[i][j]表示第i位,前面跟了j个数的最大值 那么第i+1个数,直接和第i个数的[0,m]的m+1种状态去转移即可,如果是由0或m状 ...

  5. 基础(一):SCSI硬盘与IDE硬盘有什么区别

    硬盘接口是硬盘与主机系统间的连接部件,作用是在硬盘缓存和主机内存之间传输数据.不同的硬盘接口决定着硬盘与计算机之间的连接速度,在整个系统中,硬盘接口的优劣直接影响着程序运行快慢和系统性能好坏.从整体的 ...

  6. windows server2012r2 安装NET Framework 3.5

    在Windows Server 2012上安装一些软件,比如Oracle 11g等,经常会出现下面这样的错误:“无法安装一下功能:.NET Framework 3.5(包括.NET 2.0和3.0)” ...

  7. java 简单 SocketPool

    package org.rx.socks; import lombok.extern.slf4j.Slf4j; import org.rx.common.LogWriter; import org.r ...

  8. B606 ChangeNet

    @echo off Setlocal Enabledelayedexpansion title B606 ChangeNet echo Checking... set inside=F&set ...

  9. dubbo入门学习(一)-----分布式基础理论、架构发展以及rpc、dubbo核心概念

    一.分布式基础理论 1.什么是分布式系统? <分布式系统原理与范型>定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distributed ...

  10. mybatis源码探究(-)MapperProxyFactory&MapperProxy

    在MyBatis中MapperProxyFactory,MapperProxy,MapperMethod是三个很重要的类. 弄懂了这3个类你就大概清楚Mapper接口与SQL的映射, 为什么是接口,没 ...