传送门

解题思路

  跟重组病毒这道题很像。只是有了一个询问\(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. leetcode-160场周赛-5238-找出给定方程的正整数解

    题目描述: class Solution: def findSolution(self, customfunction: 'CustomFunction', z: int) -> List[Li ...

  2. Vue学习笔记【19】——Vue中的动画(使用第三方 CSS 动画库)

    导入动画类库:  <link rel="stylesheet" type="text/css" href="./lib/animate.css& ...

  3. Android 在OnCreate()中获取控件高度与宽度

    试过在OnCreate()中获取控件高度与宽度的童鞋都知道,getWidth()与getHeight()方法返回是0,具体原因 看一下Activity的生命周期 就会明白. 上代码: 方法一: int ...

  4. Hbase集群类型|集群配置|服务器选型|磁盘容量规划

    HBase和Hadoop的集群类型 1.单机模式 主要用于开发工作,一台机器上运行所有的守护进程,或者一台机器运行多个虚拟机.一般用于评估和测试. 2.小型集群 20台机器以内的集群,不同的机器运行不 ...

  5. jQuery Validate (摘自官网)

    jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证 ...

  6. 如何加大jvm的内存和tomcat的内存

    如何扩大jvm的内存和tomcat的内存,如何让项目没有用的值得到及时的回收和清理,java项目 最佳答案   修改 tomcat 的内存方式:修改 catalina.bat在set JAVA_OPT ...

  7. 资源-.Net-ASP.NET:ASP.NET资源列表

    ylbtech-资源-.Net-ASP.NET:ASP.NET资源列表 ASP.NETFree. Cross-platform. Open source.A framework for buildin ...

  8. (14)centos7 进程管理

    一.查询进程 1. 进程显示 ps -a 显示当前所有的进程信息 -u 以用户的格式显示进程信息 -x 显示后台进程运行的参数 ps -aux #通常查看内存 USER #执行进程的用户 PID #进 ...

  9. Tomcat运行错误示例三

    Tomcat运行错误示例三 最近碰到tomcat启动的问题,如图: 以前也碰见过这种情况,这次写的时候忘记加return,所以跳出了错误,加上之后的效果,如图: 参考网址 参考网址

  10. PAT_A1124#Raffle for Weibo Followers

    Source: PAT A1124 Raffle for Weibo Followers (20 分) Description: John got a full mark on PAT. He was ...