BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)
解题思路
跟重组病毒这道题很像。只是有了一个询问\(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+线段树)的更多相关文章
- [Sdoi2017]树点涂色 [lct 线段树]
		
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
 - 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
		
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
 - 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
		
树点涂色 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...
 - BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
		
题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...
 - [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
		
题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...
 - BZOJ4817[Sdoi2017]树点涂色——LCT+线段树
		
题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ...
 - bzoj4817 & loj2001 [Sdoi2017]树点涂色   LCT + 线段树
		
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4817 https://loj.ac/problem/2001 题解 可以发现这个题就是 bzo ...
 - 【bzoj4817】树点涂色 LCT+线段树+dfs序
		
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
 - BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
		
同BZOJ3779. SDOI出原题,还是弱化版的. 吃枣药丸 #include <map> #include <cmath> #include <queue> # ...
 
随机推荐
- leetcode-160场周赛-5238-找出给定方程的正整数解
			
题目描述: class Solution: def findSolution(self, customfunction: 'CustomFunction', z: int) -> List[Li ...
 - Vue学习笔记【19】——Vue中的动画(使用第三方 CSS 动画库)
			
导入动画类库: <link rel="stylesheet" type="text/css" href="./lib/animate.css& ...
 - Android 在OnCreate()中获取控件高度与宽度
			
试过在OnCreate()中获取控件高度与宽度的童鞋都知道,getWidth()与getHeight()方法返回是0,具体原因 看一下Activity的生命周期 就会明白. 上代码: 方法一: int ...
 - Hbase集群类型|集群配置|服务器选型|磁盘容量规划
			
HBase和Hadoop的集群类型 1.单机模式 主要用于开发工作,一台机器上运行所有的守护进程,或者一台机器运行多个虚拟机.一般用于评估和测试. 2.小型集群 20台机器以内的集群,不同的机器运行不 ...
 - jQuery Validate (摘自官网)
			
jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证 ...
 - 如何加大jvm的内存和tomcat的内存
			
如何扩大jvm的内存和tomcat的内存,如何让项目没有用的值得到及时的回收和清理,java项目 最佳答案 修改 tomcat 的内存方式:修改 catalina.bat在set JAVA_OPT ...
 - 资源-.Net-ASP.NET:ASP.NET资源列表
			
ylbtech-资源-.Net-ASP.NET:ASP.NET资源列表 ASP.NETFree. Cross-platform. Open source.A framework for buildin ...
 - (14)centos7 进程管理
			
一.查询进程 1. 进程显示 ps -a 显示当前所有的进程信息 -u 以用户的格式显示进程信息 -x 显示后台进程运行的参数 ps -aux #通常查看内存 USER #执行进程的用户 PID #进 ...
 - Tomcat运行错误示例三
			
Tomcat运行错误示例三 最近碰到tomcat启动的问题,如图: 以前也碰见过这种情况,这次写的时候忘记加return,所以跳出了错误,加上之后的效果,如图: 参考网址 参考网址
 - PAT_A1124#Raffle for Weibo Followers
			
Source: PAT A1124 Raffle for Weibo Followers (20 分) Description: John got a full mark on PAT. He was ...