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]树点涂色的更多相关文章

  1. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 629  Solved: 371[Submit][Status ...

  2. [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 692  Solved: 408[Submit][Status ...

  3. bzoj4817 [Sdoi2017]树点涂色

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  4. BZOJ4817[Sdoi2017]树点涂色——LCT+线段树

    题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ...

  5. BZOJ4817 [Sdoi2017]树点涂色 【LCT + 线段树】

    题目 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进行这 ...

  6. BZOJ4817: [Sdoi2017]树点涂色(LCT)

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  7. [BZOJ4817][SDOI2017]树点涂色:Link-Cut Tree+线段树

    分析 与[BZOJ3779]重组病毒唯一的区别是多了一个链上求实链段数的操作. 因为每条实链的颜色必然不相同且一条实链上不会有两个深度相同的点(好像算法的正确性和第二个条件没什么关系,算了算了),画图 ...

  8. 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树

    [BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...

  9. 【BZOJ4817】树点涂色(LCT,线段树,树链剖分)

    [BZOJ4817]树点涂色(LCT,线段树,树链剖分) 题面 BZOJ Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义 ...

随机推荐

  1. 最长k可重线段集问题

    和那道可重区间集一样 不过这道题可能有垂直于x轴的线段,这就很烦了,直接连会有负环,判掉又会WA 可以想办法把r端点和l端点分开,又要保证答案不变 那么直接把区间l,r都乘以2,l=r时r++,否则l ...

  2. SqlServer之like、charindex、patindex 在有无索引的情况下分析

    1.环境介绍 测试环境 SQL2005 测试数据 200W条 2.环境准备 2.1建表 CREATE TABLE [dbo].[Depratments](         [Dep_id] [int] ...

  3. redis笔记总结之redis介绍

    一.Redis介绍: redis的发展历史简单的理解为因为使用类似MySql这类关系型数据库不方便进而开发的开源的.轻量级的.非关系型的,直到现在一直不断完善的一款NoSql数据库.具体的介绍大家可以 ...

  4. APNS IOS 消息推送

    一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...

  5. javascript排序、功能代码总结[长期更新]

    //基本数组去重 ///输入:向数组中添加功能函数unique ///输出:返回一个没有重复元素的数组 Array.prototype.unique = function(){ result =[]; ...

  6. 关于Roll A Ball实例练习记录

    学习中不段进步! 游戏思路:通过键盘控制白色小球,让它"捡起"柠黄色方块,捡起一个加1分,全部捡起游戏胜利! 游戏对象: Ground:绿色地面 player:  小球 Obsta ...

  7. python解决图的最短路径问题

    在hihoCoder上遇到一个算法题目,描述如下: 对图结构有了解的不难发现,这是经典的求图的最短路径问题.以下是python代码: def findMin(row): minL = max(row) ...

  8. 获取DOM节点的几种方式

    DOM 是一个树形结构,操作一个DOM节点,实际上就是这几个操作:更新.删除.添加.遍历 在操作DOM节点之前,需要通过各种方式先拿到这个DOM节点,常用的方法有: 一.通过元素类型的方法来操作: d ...

  9. 用Arduino制作一个二维码显示器

    先上图 场景是这样的, 这几天给CS系统做一个微信支付的功能,  但是生成的二维码是在前台的电脑上..不可能让用户跑到前台的电脑上去扫描...然后拿出了N年前买的Arduino 做了一个二维码显示器. ...

  10. PO BO VO DTO POJO DAO DO

    PO BO DTO VO 归在一起叫是POJO,简单java对象:DAO 是进行数据库增删改查的类,DO不确定有没有. 重点说下POJO PO 持久对象,数据: BO 业务对象,封装对象.复杂对象 , ...