\[SDOI2017 树点染色
\]

  • 题目描述

    Bob 有一棵 $ n $ 个点的有根树,其中 $ 1 $ 号点是根节点。Bob 在每个节点上涂了颜色,并且每个点上的颜色不同。

    定义一条路径的权值是,这条路径上的点(包括起点和终点)共有多少种不同的颜色。

    Bob 可能会进行这几种操作:

  • $ 1 \ x $,把点 $ x $ 到根节点的路径上的所有的点染上一种没有用过的新颜色;

  • $ 2 \ x \ y $,求 $ x $ 到 $ y $ 的路径的权值;

  • $ 3 \ x $,在以 $ x $ 为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。

  • Bob 一共会进行 $ m $ 次操作。

  • 样例输入输出

input
5 6
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5 output
3
4
2
2
  • 数据范围

    \(n \leq 10^5,m \leq 10^5\)

  • 题解

    考虑定义\(fa(x)\)如果\(x\)与父节点颜色相同就是1,否则为0,强行定义\(fa(1) = 1\)

    几率\(dis(x)\)表示从\(x\)到1路径所有的\(fa(x)\)的和,那么就是路径权值。

    操作1需要你支持一系列\(fa(x)\)的修改,并且同时维护\(dis(x)\)

    操作2访问\(x,y\)答案就是\(dis(x) + dis(y) - (2 \times (dis(lca))) + 1\)

    操作3求最大的\(dis(x)\)

    操作1可以通过\(LCT\)的\(Access\)操作实现。

    操作2和3可以用链剖+线段树维护信息。

    总评,数据结构板题。

#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int n,m,tot,cnt,Next[N<<1],head[N],tree[N<<1],Fa[N],fa[N],dep[N],size[N],Son[N],tid[N],NUM[N],top[N],Max[N*4],lazy[N*4],son[N][2];
void add(int x,int y)
{
tot++;
Next[tot]=head[x];
head[x]=tot;
tree[tot]=y;
}
void dfs(int u,int father,int depth)
{
Fa[u]=fa[u]=father;dep[u]=depth;size[u]=1;Son[u]=0;
int maxsize=0;
for (int i=head[u];i;i=Next[i])
{
int v=tree[i];
if (v==fa[u]) continue;
dfs(v,u,depth+1);
size[u]+=size[v];
if (size[v]>maxsize)
{
maxsize=size[v];
Son[u]=v;
}
}
}
void dfs1(int u,int ancestor)
{
tid[u]=++cnt;NUM[cnt]=u;top[u]=ancestor;
if (Son[u]) dfs1(Son[u],ancestor);
for (int i=head[u];i;i=Next[i])
if (tree[i]!=fa[u]&&tree[i]!=Son[u]) dfs1(tree[i],tree[i]);
}
void build(int l,int r,int id)
{
if (l==r) { Max[id]=dep[NUM[l]];return;}
int mid=(l+r)>>1;
build(l,mid,id<<1);
build(mid+1,r,id<<1|1);
Max[id]=max(Max[id<<1],Max[id<<1|1]);
}
void down(int id)
{
if (lazy[id]!=0)
{
Max[id<<1]+=lazy[id];
Max[id<<1|1]+=lazy[id];
lazy[id<<1]+=lazy[id];
lazy[id<<1|1]+=lazy[id];
lazy[id]=0;
}
}
void change(int l,int r,int id,int x,int y,int d)
{
if (l>y||r<x) return;
if (l!=r) down(id);
if (x<=l&&r<=y)
{
Max[id]+=d;
lazy[id]+=d;
return;
}
int mid=(l+r)>>1;
change(l,mid,id<<1,x,y,d);
change(mid+1,r,id<<1|1,x,y,d);
Max[id]=max(Max[id<<1],Max[id<<1|1]);
}
int query_max(int l,int r,int id,int x,int y)
{
if (l>y||r<x) return 0;
if (l!=r) down(id);
if (x<=l&&r<=y) return Max[id];
int mid=(l+r)>>1;
return max(query_max(l,mid,id<<1,x,y),query_max(mid+1,r,id<<1|1,x,y));
}
int query_sum(int l,int r,int id,int x)
{
if (l>x||r<x) return 0;
if (l!=r) down(id);
if (l==r&&l==x) return Max[id];
int mid=(l+r)>>1;
return query_sum(l,mid,id<<1,x)+query_sum(mid+1,r,id<<1|1,x);
}
int LCA(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=Fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
return x;
}
int Query(int x)
{
return query_sum(1,n,1,tid[x]);
}
inline bool isRoot(int x) { return (son[fa[x]][0]!=x)&&(son[fa[x]][1]!=x);}
inline void Rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if (son[y][0]==x) l=0;else l=1;
r=l^1;
if (!isRoot(y))
{
if (son[z][0]==y) son[z][0]=x;else son[z][1]=x;
}
fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
}
inline void splay(int x)
{
while (!isRoot(x))
{
int y=fa[x],z=fa[y];
if (!isRoot(y))
{
if ((son[z][0]==y)^(son[y][0]==x)) Rotate(x);
else Rotate(y);
}
Rotate(x);
}
}
inline void access(int x)
{
for (int i=0;x;i=x,x=fa[x])
{
splay(x);
if (son[x][1])
{
int id=son[x][1];
while (son[id][0]) id=son[id][0];
change(1,n,1,tid[id],tid[id]+size[id]-1,1);
}
if (i)
{
int id=i;
while (son[id][0]) id=son[id][0];
change(1,n,1,tid[id],tid[id]+size[id]-1,-1);
}
son[x][1]=i;
}
}
int main()
{
scanf("%d%d",&n,&m);
tot=cnt=0;
for (int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(1,0,1);
dfs1(1,1);
build(1,n,1);
while (m--)
{
int id,x,y;
scanf("%d",&id);
if (id==1) { scanf("%d",&x);access(x);}
if (id==2) { scanf("%d%d",&x,&y);printf("%d\n",Query(x)+Query(y)-Query(LCA(x,y))*2+1);}
if (id==3) { scanf("%d",&x);printf("%d\n",query_max(1,n,1,tid[x],tid[x]+size[x]-1));}
}
return 0;
}

SDOI2017 树点染色的更多相关文章

  1. loj2001[SDOI2017]树点染色

    题意:给你一棵树,一开始每个点上的颜色互不相同.三种操作:op1:x到根的路径上的点都染上一种新的颜色.op2:设一条路径的权值为val(x,y),求x到y路径的val.op3:询问x的子树中最大的到 ...

  2. SDOI2017树点染色

    题目链接 发现1操作很像lct中的access,然后它每次染的又是一个新颜色,因此同一个颜色就在同一颗splay里了,且一个点到根的权值val[i]也就是到根路径上虚边的个数,然后看access时会对 ...

  3. 洛谷3703 [SDOI2017] 树点染色 【LCT】【线段树】

    题目分析: 操作一很明显等价于LCT上的access操作,操作二是常识,操作三转化到dfs序上求最大值也是常识.access的时候顺便在线段树中把对应部分-1,把右子树的子树+1即可. 代码: #in ...

  4. codevs 5963 [SDOI2017]树点染色

     [题解]: #include<cstdio> #include<cstring> #include<iostream> using namespace std; ...

  5. [Sdoi2017]树点涂色 [lct 线段树]

    [Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...

  6. P3703 [SDOI2017]树点涂色

    P3703 [SDOI2017]树点涂色 链接 分析: 首先对于询问,感觉是线段树维护dfs序,每个点记录到根的颜色个数.第二问差分,第三问区间取max. 那么考虑修改,每次将一个点的颜色变成和父节点 ...

  7. codevs 1191 树轴染色 线段树区间定值,求和

    codevs 1191 树轴染色 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.codevs.cn/problem/1191/ Des ...

  8. 【LG3703】[SDOI2017]树点涂色

    [LG3703][SDOI2017]树点涂色 题面 洛谷 题解 更博辣,更博辣!!! 猪年的第一篇博客 一次只能染根到\(x\),且染的颜色未出现过 这句话是我们解题的关键. 设\(x\)到根的颜色数 ...

  9. HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)

    题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树).当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工 ...

随机推荐

  1. 数组转xls格式的excel文件&数据转csv格式的excle

    /** * 数组转xls格式的excel文件 * @param array $data 需要生成excel文件的数组 * @param string $filename 生成的excel文件名 * 示 ...

  2. 存储-docker存储(12)

    storage driver 和 data volume 是容器存放数据的两种方式 storage driver方式 docker info | grep "Storage Driver&q ...

  3. (转)Spring Boot干货系列:(七)默认日志logback配置解析

    转:http://tengj.top/2017/04/05/springboot7/ 前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的, ...

  4. ceph-报错日志

    由于时钟不一致问题,导致ceph存储有问题 clock skew时钟偏移overalladj. 全部的:全体的:一切在内的stampedadj. 铭刻的:盖上邮戳的:顿足的 beaconvt. 照亮, ...

  5. 46、tensorflow入门初步,手写识别0,1,2,3,4,5,6

    1.使用tensorflow的SoftMax函数,对手写数字进行识别 Administrator@SuperComputer MINGW64 ~ $ docker run -it -p 8888:88 ...

  6. NetworkComms V2版本与V3版本语法的差异

    NetworkComms网络通信框架序言 NetworkComms通信框架中V3版本是一次重要的升级,底层做了诸多改变,但语法上与V2版本相比,差不并不大. 监听端口: V3中 IPEndPoint ...

  7. cmd 运行 java 文件

    在安装好jdk 并配置好环境变量的情况下 原因一:没有指定class文件的路径 例如HI是变异好的class文件,并且在d:/RJAZB里面 如果写成 Java HI  则会报错 正确做法 java ...

  8. C/C++程序员 面试经历总结

    最近在找工作,遇到了一些面试题,很惭愧的是很多都没答上来. 现在把一些问题总结一下,算是记录一下面试的经历吧.以后有空简单地回答一下, 同时也欢迎各位同仁解答,共同学习一下吧!   一.嵌入式C语言面 ...

  9. 树的重心(DFS)

    ;vector< ; i < v[node].size() ; i++){ , ; i <= n- ; i++){ cin >> a >> b; v[a].p ...

  10. png图片使用opacity在ie中出现黑边情况

    JQuery动画的淡入淡出效果,用在PNG24的图片上,在IE7.IE8下会出现黑边框. 有些人觉得很奇怪,为什么?潘?E6正常,反而在IE7.8下却有黑边呢. 其实问题出在filter属性上.IE6 ...