传送门

解题思路

  跟重组病毒这道题很像。只是有了一个询问\(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. Cache技术―OSCache

    Cache技术―OSCache 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://aumy2008.blogbus.com/logs/36462938.html 一.简介 ...

  2. k8s集群搭建之一:基础环境

    一按照kubernetes对软件和硬件的要求: 二准备的主机系统以及ip配置 角色 系统 IP k8s-master centos7.4 192.168.137.66 k8s-node1 centos ...

  3. Spring Cloud Alibaba 从孵化到 "挂牌" 之旅

    背景 2014 年,Spring Boot 1.0 发布.Spring Boot 的发布绝对是 Pivotal 历史上具有里程碑意义的事件,它让我们能够非常简便地开发 Spring 应用,屏蔽了各种配 ...

  4. BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))

    [传送门[(https://www.lydsy.com/JudgeOnline/problem.php?id=3238) 解题思路 首先原式可以把\(len\)那部分直接算出来,然后通过后缀数组求\( ...

  5. docker仓库管理(9)

    使用公共 Registry Docker Hub 是 Docker 公司维护的公共 Registry.用户可以将自己的镜像保存到 Docker Hub 免费的 repository 中.如果不希望别人 ...

  6. Vi/Vim查找,替换,统计使用方法

    Vi/Vim查找替换使用方法 vi/vim 中可以使用 :s 命令来替换字符串.该命令有很多种不同细节使用方法,可以实现复杂的功能,记录几种在此,方便以后查询. 可以使用 # 作为分隔符,此时中间出现 ...

  7. Linux内核知识杂记

    1.内核调试手段 1.printk打印内核状态 2.产生opps时使用GDB查看调用栈 2.内核空间和用户空间区别,通信方式有哪些? Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,L ...

  8. 安装debian总结以及编译linux内核

    1. 安装debian 使用unetbootin(http://unetbootin.sourceforge.net/)来创建启动盘,并且下载debian的基本包. 将磁盘进行压缩操作,并且保留出一个 ...

  9. LaTex 插入图像,以及应用表格

    插入图像 参考:http://www.ctex.org/documents/latex/graphics/ 1: \includegraphics[width=20mm]{head.png} 应用表格 ...

  10. CentOS 7 启用中文输入法

    $HOME/.xinitrc LANG="zh_CN.UTF-8" exec startxfce4