BZOJ4817[Sdoi2017]树点涂色——LCT+线段树
题目描述
输入
输出
样例输入
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5
样例输出
4
2
2
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int c[100010][2];
int fa[100010];
int tag[400010];
int f[100010][18];
int dep[100010];
int mx[400010];
int dfn;
int tot;
int x,y;
int n,m;
int opt;
int head[100010];
int next[200010];
int to[200010];
int q[100010];
int s[100010];
int t[100010];
void add(int x,int y)
{
next[++tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void pushup(int rt)
{
mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}
void pushdown(int rt)
{
if(tag[rt])
{
tag[rt<<1]+=tag[rt];
tag[rt<<1|1]+=tag[rt];
mx[rt<<1]+=tag[rt];
mx[rt<<1|1]+=tag[rt];
tag[rt]=0;
}
}
void build(int rt,int l,int r)
{
if(l==r)
{
mx[rt]=dep[q[l]];
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void change(int rt,int l,int r,int L,int R,int v)
{
if(L<=l&&r<=R)
{
tag[rt]+=v;
mx[rt]+=v;
return ;
}
pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid)
{
change(rt<<1,l,mid,L,R,v);
}
if(R>mid)
{
change(rt<<1|1,mid+1,r,L,R,v);
}
pushup(rt);
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
return mx[rt];
}
pushdown(rt);
int mid=(l+r)>>1;
int res=0;
if(L<=mid)
{
res=max(res,query(rt<<1,l,mid,L,R));
}
if(R>mid)
{
res=max(res,query(rt<<1|1,mid+1,r,L,R));
}
return res;
}
int ask(int rt,int l,int r,int k)
{
if(l==r)
{
return mx[rt];
}
pushdown(rt);
int mid=(l+r)>>1;
if(k<=mid)
{
return ask(rt<<1,l,mid,k);
}
else
{
return ask(rt<<1|1,mid+1,r,k);
}
}
bool is_root(int rt)
{
return rt!=c[fa[rt]][0]&&rt!=c[fa[rt]][1];
}
bool get(int rt)
{
return rt==c[fa[rt]][1];
}
void rotate(int rt)
{
int x=fa[rt];
int y=fa[x];
int k=get(rt);
if(!is_root(x))
{
c[y][get(x)]=rt;
}
c[x][k]=c[rt][k^1];
fa[c[rt][k^1]]=x;
c[rt][k^1]=x;
fa[x]=rt;
fa[rt]=y;
}
void splay(int rt)
{
for(int x;!is_root(rt);rotate(rt))
{
if(!is_root(x=fa[rt]))
{
rotate(get(x)==get(rt)?x:rt);
}
}
}
void link(int x,int y)
{
fa[x]=y;
}
int find(int rt)
{
while(c[rt][0])
{
rt=c[rt][0];
}
return rt;
}
void access(int rt)
{
for(int x=0;rt;x=rt,rt=fa[rt])
{
splay(rt);
if(x)
{
int son=find(x);
change(1,1,n,s[son],t[son],-1);
}
if(c[rt][1])
{
int son=find(c[rt][1]);
change(1,1,n,s[son],t[son],1);
}
c[rt][1]=x;
}
}
void dfs(int x)
{
s[x]=++dfn;
q[dfn]=x;
for(int i=1;i<=17;i++)
{
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=f[x][0])
{
f[to[i]][0]=x;
link(to[i],x);
dep[to[i]]=dep[x]+1;
dfs(to[i]);
}
}
t[x]=dfn;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])
{
swap(x,y);
}
int d=dep[x]-dep[y];
for(int i=0;i<=17;i++)
{
if(d&(1<<i))
{
x=f[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=17;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dep[1]=1;
dfs(1);
build(1,1,n);
while(m--)
{
scanf("%d",&opt);
if(opt==1)
{
scanf("%d",&x);
access(x);
}
else if(opt==2)
{
scanf("%d%d",&x,&y);
int anc=lca(x,y);
int ans=ask(1,1,n,s[x])+ask(1,1,n,s[y])-2*ask(1,1,n,s[anc])+1;
printf("%d\n",ans);
}
else
{
scanf("%d",&x);
printf("%d\n",query(1,1,n,s[x],t[x]));
}
}
}
BZOJ4817[Sdoi2017]树点涂色——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 ...
- [Sdoi2017]树点涂色 [lct 线段树]
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...
- bzoj4817 & loj2001 [Sdoi2017]树点涂色 LCT + 线段树
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4817 https://loj.ac/problem/2001 题解 可以发现这个题就是 bzo ...
- BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
同BZOJ3779. SDOI出原题,还是弱化版的. 吃枣药丸 #include <map> #include <cmath> #include <queue> # ...
- BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)
传送门 解题思路 跟重组病毒这道题很像.只是有了一个询问\(2\)的操作,然后询问\(2\)的答案其实就是\(val[x]+val[y]-2*val[lca(x,y)]+1\)(画图理解).剩下的操作 ...
随机推荐
- idea打jar包并部署java web项目
1.idea打jar包 (idea提供界面是jar包方式) 点击package,结束就OK,jar包一般放在target里面 部署项目 1.停止之前的服务: 查到到java的所有进程:ps -ef|g ...
- SAP QA32 做使用决策系统报错:分类数据的不一致性=>交易终止
SAP QA32 做使用决策系统报错:分类数据的不一致性=>交易终止 QA32,对如下检验批做处理,系统报错, 试图使用MSC3N去显示这个批次主数据,同样报错, 原因在于批次的分类数据产生后, ...
- 深度 | AI芯片终极之战
深度 | AI芯片终极之战 https://mp.weixin.qq.com/s?__biz=MzA4MTQ4NjQzMw==&mid=2652712307&idx=1&sn= ...
- SqlServer主键和自增长设置
SqlServer主键和自增长设置 Intro 有时候有些 sql 语句有些不太记得了,谨以此文备忘. 设置主键以及自增长可分两种情况: 新创建表 表已创建但是没有设置主键和自增长 新创建表 创建表 ...
- 测试系统工程师TSE需要具备的四项能力
文/杨学明 如今,国内所有的研发型的公司都有测试部门,无论测试团队大小,都有测试组长,测试经理,测试工程师等头衔,但随着产品和业务的质量要求越来越高,产品的市场竞争越来越激烈,公司领导对产品测试的要求 ...
- Jenkins系统监测(转)
Jenkins系统监测 Jenkins 是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上.同时 Jenkins 能实施监控集成中存在 ...
- 谈谈当代大学生学习IT技术的必要性。
21世纪,人类社会已经从工业时代全面进入信息化时代,IT技术的发展正在影响人类的日常生活.比如,外卖平台给人们的用餐提供了更多的选择,移动支付颠覆了传统的支付方式.网购使得人们的购物更加方便,真正做到 ...
- Python开发【内置模块篇】datetime
获取当前日期和时间 >>> from datetime import datetime >>> now = datetime.now() >>> ...
- he
弄好这个网站---to thi tha think 好这个---, 很温馨 那时候我还在看. 前一段时候看yibenhaoshu,走出来的才是理性,所以现在才是理性的看待的. 回头再看看两年前的事情, ...
- android的listview以及画线--to thi tha
https://www.cnblogs.com/896240130Master/p/6135165.html 这个的 https://www.jianshu.com/p/5522470760c1