bzoj千题计划275:bzoj4817: [Sdoi2017]树点涂色
http://www.lydsy.com/JudgeOnline/problem.php?id=4817
lct+线段树+dfs序
操作1:access
操作2:u到根的-v到根的-lca到根的*2+1
操作3:查询线段树区间最大值
1A,嘎嘎嘎
#include<cmath>
#include<cstdio>
#include<iostream> using namespace std; #define max(x,y) ((x)>(y) ? (x) : (y)) #define N 100001 int n;
int front[N],to[N<<],nxt[N<<],tot; int id[N],dy[N],lst[N],tim;
int dep[N]; int lim,F[N][]; int mx[N<<],tag[N<<]; int root;
int fa[N],ch[N][];
bool rev[N]; int st[N],top; int ans; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} void dfs(int x)
{
id[x]=++tim;
dy[tim]=x;
dep[x]=dep[fa[x]]+;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x])
{
F[to[i]][]=fa[to[i]]=x;
dfs(to[i]);
}
lst[x]=tim;
} void build(int k,int l,int r)
{
if(l==r)
{
mx[k]=dep[dy[l]];
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
mx[k]=max(mx[k<<],mx[k<<|]);
} void down(int k)
{
mx[k<<]+=tag[k];
tag[k<<]+=tag[k];
mx[k<<|]+=tag[k];
tag[k<<|]+=tag[k];
tag[k]=;
} void change(int k,int l,int r,int opl,int opr,int w)
{
if(l>=opl && r<=opr)
{
mx[k]+=w;
tag[k]+=w;
return;
}
if(tag[k]) down(k);
int mid=l+r>>;
if(opl<=mid) change(k<<,l,mid,opl,opr,w);
if(opr>mid) change(k<<|,mid+,r,opl,opr,w);
mx[k]=max(mx[k<<],mx[k<<|]);
} void Change(int x,int w)
{
if(x==root) change(,,n,,n,w);
else if(id[x]>id[root] && id[x]<=lst[root]) change(,,n,id[x],lst[x],w);
else
{
int t=root,c=dep[root]-dep[x]-;
for(int i=lim;i>=;--i)
if(c&(<<i)) t=F[t][i];
if(id[t]>) change(,,n,,id[t]-,w);
if(lst[t]<n) change(,,n,lst[t]+,n,w);
}
} int query1(int k,int l,int r,int pos)
{
if(l==r) return mx[k];
if(tag[k]) down(k);
int mid=l+r>>;
if(pos<=mid) return query1(k<<,l,mid,pos);
return query1(k<<|,mid+,r,pos);
} void query2(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr)
{
ans=max(ans,mx[k]);
return;
}
if(tag[k]) down(k);
int mid=l+r>>;
if(opl<=mid) query2(k<<,l,mid,opl,opr);
if(opr>mid) query2(k<<|,mid+,r,opl,opr);
} void push_down(int x)
{
if(rev[x])
{
if(ch[x][]) rev[ch[x][]]^=;
if(ch[x][]) rev[ch[x][]]^=;
rev[x]^=;
}
} bool is_root(int x)
{
return ch[fa[x]][]!=x && ch[fa[x]][]!=x;
} bool get_son(int x)
{
return ch[fa[x]][]==x;
} void rotate(int x)
{
int y=fa[x],z=fa[y];
bool k=ch[y][]==x;
if(!is_root(y)) ch[z][ch[z][]==y]=x;
ch[y][k]=ch[x][k^]; ch[x][k^]=y;
fa[x]=z; fa[y]=x; fa[ch[y][k]]=y;
} void splay(int x)
{
st[top=]=x;
for(int i=x;!is_root(i);i=fa[i]) st[++top]=fa[i];
for(int i=top;i;--i) push_down(st[i]);
int y;
while(!is_root(x))
{
y=fa[x];
if(!is_root(y)) rotate(get_son(x)==get_son(y) ? x : y );
rotate(x);
}
} int find_root(int x)
{
push_down(x);
while(ch[x][])
{
x=ch[x][];
push_down(x);
}
return x;
} void access(int x)
{
int t=;
while(x)
{
splay(x);
if(ch[x][]) Change(find_root(ch[x][]),);
ch[x][]=t;
if(t) Change(find_root(t),-);
t=x; x=fa[x];
}
} int get_lca(int u,int v)
{
if(dep[u]<dep[v]) std::swap(u,v);
int d=dep[u]-dep[v];
for(int i=lim;i>=;--i)
if(d&(<<i)) u=F[u][i];
if(u==v) return u;
for(int i=lim;i>=;--i)
if(F[u][i]!=F[v][i]) u=F[u][i],v=F[v][i];
return F[u][];
} int main()
{
int m;
read(n); read(m);
lim=log(n)/log();
int u,v;
for(int i=;i<n;++i)
{
read(u); read(v);
add(u,v);
}
dfs();
for(int j=;j<=lim;++j)
for(int i=;i<=n;++i)
F[i][j]=F[F[i][j-]][j-];
build(,,n);
root=;
int ty;
int lca;
while(m--)
{
read(ty); read(u);
if(ty==) access(u);
else if(ty==)
{
read(v);
lca=get_lca(u,v);
printf("%d\n",query1(,,n,id[u])+query1(,,n,id[v])-query1(,,n,id[lca])*+);
}
else
{
ans=;
query2(,,n,id[u],lst[u]);
printf("%d\n",ans);
}
}
}
bzoj千题计划275:bzoj4817: [Sdoi2017]树点涂色的更多相关文章
- [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 629 Solved: 371[Submit][Status ...
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 692 Solved: 408[Submit][Status ...
- bzoj4817 [Sdoi2017]树点涂色
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- BZOJ4817[Sdoi2017]树点涂色——LCT+线段树
题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ...
- BZOJ4817 [Sdoi2017]树点涂色 【LCT + 线段树】
题目 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进行这 ...
- BZOJ4817: [Sdoi2017]树点涂色(LCT)
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- [BZOJ4817][SDOI2017]树点涂色:Link-Cut Tree+线段树
分析 与[BZOJ3779]重组病毒唯一的区别是多了一个链上求实链段数的操作. 因为每条实链的颜色必然不相同且一条实链上不会有两个深度相同的点(好像算法的正确性和第二个条件没什么关系,算了算了),画图 ...
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
- 【BZOJ4817】树点涂色(LCT,线段树,树链剖分)
[BZOJ4817]树点涂色(LCT,线段树,树链剖分) 题面 BZOJ Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义 ...
随机推荐
- 2.3.2 InnoDB内存
前面介绍了一些InnoDB的体系架构(http://www.cnblogs.com/tanwt/p/8530987.html) 接下来介绍一下InnoDB 的内存 1.缓冲池 首先我们需要了解的是In ...
- [SCOI2008]斜堆
题目大意 1.题目描述 斜堆(skew heap)是一种常用的数据结构. 它也是二叉树,且满足与二叉堆相同的堆性质: 每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小. . 但斜堆不必是平衡 ...
- 【BZOJ2816】【ZJOI2012】网络(Link-Cut Tree)
[BZOJ2816][ZJOI2012]网络(Link-Cut Tree) 题面 题目描述 有一个无向图G,每个点有个权值,每条边有一个颜色.这个无向图满足以下两个条件: 对于任意节点连出去的边中,相 ...
- 【BZOJ1924】【SDOI2010】所驼门王的宝藏(Tarjan,SPFA)
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- 【Spring源码分析】非懒加载的单例Bean初始化过程(下篇)
doCreateBean方法 上文[Spring源码分析]非懒加载的单例Bean初始化过程(上篇),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下 ...
- 如何在Win10下安装MySQL 5.7绿色版
一.背景 系统升级到Win10后准备在本地搭建一个MySQL环境,用于研究学习.在网上找了很多其他人写的经验总结,Step by step的做,不断的遇到问题,没有成功. 最后老老实实的去读Mysql ...
- Gradle下载 Jar 包
使用此方法下载Jar包的前提是已经配置好了Gradle的环境了,配置好的标志是在终端输入gradle不提示command not found. 1. 编写build.gradle文件代码: apply ...
- 【翻译】《向“弹跳球”演示程序添加新功能》 in MDN
文章地址: https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Objects/%E5%90%91%E2%80%9C%E5%BC%B9% ...
- assert断言检测
assert 是宏,非函数,包含在assert.h 头文件中. 如果其后面括号里的值为假,则程序终止运行,并提示出错.这个 宏只在 Debug 版本上起作用,而在 Release 版本被编译器完全优化 ...
- 关于Videodownload helper的下载问题
Videodownload helper是火狐浏览器的一个视频音频嗅探插件, 解压文件的时候处于解压状态还没有解压完的时候不能关闭原来的窗口 所以这个下载软件也同理.没有下载完一个视频之前不能把这个窗 ...